| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- import Connect from 'connect';
- import { ServerResponse } from 'node:http';
- import https from 'https';
- import { parse as parseCookie } from 'cookie';
- import { sendReLogin } from '../SSE/server';
- import casdoorServer from 'casdoor-nodejs-sdk';
- import {
- ServerUrl,
- ClientId,
- SecretKey,
- Certificate,
- AppName,
- OrganizationName
- } from './config';
- const sdk = new casdoorServer.SDK({
- endpoint: ServerUrl,
- clientId: ClientId,
- clientSecret: SecretKey,
- certificate: Certificate,
- orgName: OrganizationName,
- appName: AppName
- }, {
- httpsAgent: new https.Agent({ rejectUnauthorized: false })
- })
- // 未授权响应
- function resUnauthorized(res: ServerResponse<Connect.IncomingMessage>, cookies?: Record<string, string | undefined>) {
- res.statusCode = 401; // Unauthorized
- res.setHeader('Content-Type', 'text/plain')
- res.end('Unauthorized')
- if (cookies) {
- const session_id = cookies['session_id']
- if (session_id) {
- // 重新登录
- setTimeout(() => {
- sendReLogin(session_id);
- }, 3000);
- }
- }
- }
- // 处理登录请求
- async function handleSignin(url: URL): Promise<{ access_token: string; refresh_token: string; } | undefined> {
- const code = url.searchParams.get('code');
- const state = url.searchParams.get('state');
- if (code && state) {
- const token = await sdk.getAuthToken(code);
- return token
- }
- return undefined
- }
- // 验证Token
- function verifyToken(token: string): boolean {
- try {
- sdk.parseJwtToken(token);
- return true;
- } catch (err) {
- console.error("token verify failed.");
- console.error(err);
- }
- return false;
- }
- // 刷新Token
- async function refreshToken(refresh_token: string) {
- const tokenGroup = await sdk.refreshToken(refresh_token).catch(err => {
- console.error("refresh token failed.")
- console.error(err)
- return undefined
- })
- return tokenGroup;
- }
- export default async function AuthMid(req: Connect.IncomingMessage, res: ServerResponse<Connect.IncomingMessage>, next: Connect.NextFunction) {
- const BaseUrl = process.env.BASE_URL
- if (req.url) {
- const url = new URL(req.url, "https://raspberrypi.dev");
- // 请求保护资源,验证JWT
- if (!url.pathname.startsWith(BaseUrl + 'casdoor') && url.pathname.endsWith('.md')) {
- console.log("verify JWT")
- const cookieStr = req.headers.cookie
- if (!cookieStr) {
- resUnauthorized(res);
- return
- } else {
- const cookies = parseCookie(cookieStr);
- console.log(cookies)
- const token = cookies['token'];
- const refresh_token = cookies['refresh_token'];
- // 验证Token
- if (token && verifyToken(token)) {
- // 验证成功
- next();
- return
- }
- // 验证刷新Token
- if (refresh_token && verifyToken(refresh_token)) {
- // 刷新Token
- const tokenGroup = await refreshToken(refresh_token);
- if (tokenGroup) {
- // 刷新成功,设置token
- res.setHeader('Set-Cookie', [
- `token=${tokenGroup.access_token}; HttpOnly; Path=/; Max-Age=86400; SameSite=Strict`,
- `refresh_token=${tokenGroup.refresh_token}; HttpOnly; Path=/; SameSite=Strict`
- ]);
- next();
- return
- }
- }
- resUnauthorized(res, cookies);
- return
- }
- }
- // 处理登录查询
- if (url.pathname.startsWith(BaseUrl + 'api/islogin')) {
- console.log("islogin")
- const cookieStr = req.headers.cookie
- if (cookieStr) {
- const cookies = parseCookie(cookieStr);
- const token = cookies['token'];
- const refresh_token = cookies['refresh_token'];
- // 验证Token
- if (token && verifyToken(token)) {
- // 验证成功
- res.statusCode = 200;
- res.setHeader('Content-Type', 'text/plain')
- res.end(token)
- return
- }
- // 验证刷新Token
- if (refresh_token && verifyToken(refresh_token)) {
- // 刷新Token
- const tokenGroup = await refreshToken(refresh_token);
- if (tokenGroup) {
- // 刷新成功,设置token
- res.setHeader('Set-Cookie', [
- `token=${tokenGroup.access_token}; HttpOnly; Path=/; Max-Age=86400; SameSite=Strict`,
- `refresh_token=${tokenGroup.refresh_token}; HttpOnly; Path=/; SameSite=Strict`
- ]);
- res.statusCode = 200;
- res.setHeader('Content-Type', 'text/plain')
- res.end(token)
- return
- }
- }
- }
- resUnauthorized(res);
- return
- }
- // 处理登录请求
- if (url.pathname.startsWith(BaseUrl + 'api/signin')) {
- console.log("handleSignin")
- const signinToken = await handleSignin(url).catch((err) => {
- console.log("handleSignin: ", err)
- });
- console.log("signinToken: ", signinToken)
- if (signinToken) {
- res.setHeader('Set-Cookie', [
- `token=${signinToken.access_token}; HttpOnly; Path=/; Max-Age=86400; SameSite=Strict`,
- `refresh_token=${signinToken.refresh_token}; HttpOnly; Path=/; SameSite=Strict`
- ])
- res.statusCode = 200;
- res.setHeader('Content-Type', 'application/json')
- res.end(JSON.stringify(signinToken))
- return
- }
- }
- // 处理登录请求
- if (url.pathname.startsWith(BaseUrl + 'api/exit')) {
- console.log("exit")
- // 清除token
- res.setHeader('Set-Cookie', [
- `token=; HttpOnly; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict`,
- `refresh_token=; HttpOnly; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=Strict`
- ])
- res.statusCode = 200;
- res.setHeader('Content-Type', 'text/plain')
- res.end("Exit successful.")
- return
- }
- }
-
- // 继续执行下一个中间件
- next();
- }
|