Implementation NextJS with Authorization Security
Published in
3 min readJan 29, 2022
with NestJS Backend & Keycloak Authorization Server
Summary
- Introduction
- Login Redirect to Keycloak
- Add Private Page
- NextJS Demo
- References
1. Introduction
Environment
- Frontend — NextJS
- Backend — NestJS
- Authorization — Keycloak
React-Keycloak
Container nest /app
docker-compose exec app bashnpm install react-keycloak --savenpm uninstall keycloak-js --save(retira)npm install @react-keycloak/ssr --save
npm install keycloak-js --save
2. Login Redirect to Keycloak
- login.tsx
import { useKeycloak } from "@react-keycloak/ssr";import {KeycloakInstance} from 'keycloak-js';import { useEffect } from "react";const LoginPage = () => {const { initialized, keycloak } = useKeycloak<KeycloakInstance>();//keycloak?.authenticatedconst {login = () => {}, authenticated} = keycloak || {};useEffect( () => {if(!initialized) {return;}if(!authenticated){login({redirectUri: 'http:localhost:3001/private'});}}, [login,authenticated, initialized])return null;};export default LoginPage;
Two Token
- Authorization Token => IdToken / Authentication Token
- Access Token => kxToken
3. Add Private Page
- Install Json Web Token
- https://www.npmjs.com/package/jsonwebtoken
docker-compose exec app bashnpm install jsonwebtoken --savenpm install @types/jsonwebtoken --save
- /util/auth.ts
export type Payload = KeycloakTokenParsed &
KeycloakProfile;
export type Token = { token: string; payload: Payload };
type Request = { headers: { cookie?: any } };
export function validateAuth(req?: Request): Token | boolean {
const cookies = parseCookies(req);
if (!cookies.kcToken) {
return false;
}
const token = Buffer.from(cookies.kcToken, "base64").toString("utf8");
const payloadOrFalse = verifyToken(token, process.env.JWT_SECRET as string);
return payloadOrFalse
? ({ token, payload: payloadOrFalse } as any)
: payloadOrFalse;
}
//verificação completa
export function verifyToken(token: string, key: string): JwtPayload | false {
try {
return jwt.verify(token, key, { ignoreExpiration: false }) as JwtPayload;
} catch (e) {
console.error(e, token, key);
return false;
}
}