mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
支持多端登录
This commit is contained in:
parent
4c1551c309
commit
f48b91dc0a
|
@ -117,7 +117,9 @@ export function createRandomString(min: number, max: number): string {
|
|||
export function getToken(req: any) {
|
||||
const { authorization } = req.headers;
|
||||
if (authorization && authorization.split(' ')[0] === 'Bearer') {
|
||||
return authorization.split(' ')[1];
|
||||
return (authorization.split(' ')[1] as string)
|
||||
.replace('mobile-', '')
|
||||
.replace('desktop-', '');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -184,3 +186,36 @@ export async function getNetIp(req: any) {
|
|||
return { address: `获取失败`, ip };
|
||||
}
|
||||
}
|
||||
|
||||
export function getPlatform(userAgent: string): 'mobile' | 'desktop' {
|
||||
const ua = userAgent.toLowerCase();
|
||||
const testUa = (regexp: RegExp) => regexp.test(ua);
|
||||
const testVs = (regexp: RegExp) =>
|
||||
(ua.match(regexp) || [])
|
||||
.toString()
|
||||
.replace(/[^0-9|_.]/g, '')
|
||||
.replace(/_/g, '.');
|
||||
|
||||
// 系统
|
||||
let system = 'unknow';
|
||||
if (testUa(/windows|win32|win64|wow32|wow64/g)) {
|
||||
system = 'windows'; // windows系统
|
||||
} else if (testUa(/macintosh|macintel/g)) {
|
||||
system = 'macos'; // macos系统
|
||||
} else if (testUa(/x11/g)) {
|
||||
system = 'linux'; // linux系统
|
||||
} else if (testUa(/android|adr/g)) {
|
||||
system = 'android'; // android系统
|
||||
} else if (testUa(/ios|iphone|ipad|ipod|iwatch/g)) {
|
||||
system = 'ios'; // ios系统
|
||||
}
|
||||
|
||||
let platform = 'desktop';
|
||||
if (system === 'windows' || system === 'macos' || system === 'linux') {
|
||||
platform = 'desktop';
|
||||
} else if (system === 'android' || system === 'ios' || testUa(/mobile/g)) {
|
||||
platform = 'mobile';
|
||||
}
|
||||
|
||||
return platform as 'mobile' | 'desktop';
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ import routes from '../api';
|
|||
import config from '../config';
|
||||
import jwt from 'express-jwt';
|
||||
import fs from 'fs';
|
||||
import { getToken } from '../config/util';
|
||||
import { getPlatform, getToken } from '../config/util';
|
||||
import Container from 'typedi';
|
||||
import OpenService from '../services/open';
|
||||
import rewrite from 'express-urlrewrite';
|
||||
|
@ -17,7 +17,10 @@ export default ({ app }: { app: Application }) => {
|
|||
app.use(bodyParser.json({ limit: '50mb' }));
|
||||
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
||||
app.use(
|
||||
jwt({ secret: config.secret as string, algorithms: ['HS384'] }).unless({
|
||||
jwt({
|
||||
secret: config.secret as string,
|
||||
algorithms: ['HS384'],
|
||||
}).unless({
|
||||
path: [
|
||||
'/api/login',
|
||||
'/api/crons/status',
|
||||
|
@ -27,6 +30,16 @@ export default ({ app }: { app: Application }) => {
|
|||
}),
|
||||
);
|
||||
|
||||
app.use((req: Request, res, next) => {
|
||||
if (!req.headers) {
|
||||
req.platform = 'desktop';
|
||||
} else {
|
||||
const platform = getPlatform(req.headers['user-agent'] || '');
|
||||
req.platform = platform;
|
||||
}
|
||||
return next();
|
||||
});
|
||||
|
||||
app.use(async (req, res, next) => {
|
||||
const headerToken = getToken(req);
|
||||
if (req.path.startsWith('/open/')) {
|
||||
|
@ -66,8 +79,12 @@ export default ({ app }: { app: Application }) => {
|
|||
|
||||
const data = fs.readFileSync(config.authConfigFile, 'utf8');
|
||||
if (data) {
|
||||
const { token } = JSON.parse(data);
|
||||
if (token && headerToken === token) {
|
||||
const { token = '', tokens = {} } = JSON.parse(data);
|
||||
console.log(tokens);
|
||||
console.log(req.platform);
|
||||
console.log(tokens[req.platform]);
|
||||
if (headerToken === token || tokens[req.platform] === headerToken) {
|
||||
console.log('yes');
|
||||
return next();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Service, Inject } from 'typedi';
|
||||
import winston from 'winston';
|
||||
import { createRandomString, getNetIp } from '../config/util';
|
||||
import { createRandomString, getNetIp, getPlatform } from '../config/util';
|
||||
import config from '../config';
|
||||
import * as fs from 'fs';
|
||||
import _ from 'lodash';
|
||||
|
@ -29,7 +29,7 @@ export default class AuthService {
|
|||
username: string;
|
||||
password: string;
|
||||
},
|
||||
req: any,
|
||||
req: Request,
|
||||
needTwoFactor = true,
|
||||
): Promise<any> {
|
||||
if (!fs.existsSync(config.authConfigFile)) {
|
||||
|
@ -49,6 +49,7 @@ export default class AuthService {
|
|||
lastaddr,
|
||||
twoFactorActivated,
|
||||
twoFactorActived,
|
||||
tokens = {},
|
||||
} = content;
|
||||
// patch old field
|
||||
twoFactorActivated = twoFactorActivated || twoFactorActived;
|
||||
|
@ -94,6 +95,10 @@ export default class AuthService {
|
|||
|
||||
this.updateAuthInfo(content, {
|
||||
token,
|
||||
tokens: {
|
||||
...tokens,
|
||||
[req.platform]: token,
|
||||
},
|
||||
lastlogon: timestamp,
|
||||
retries: 0,
|
||||
lastip: ip,
|
||||
|
@ -214,7 +219,14 @@ export default class AuthService {
|
|||
return isValid;
|
||||
}
|
||||
|
||||
public async twoFactorLogin({ username, password, code }, req) {
|
||||
public async twoFactorLogin(
|
||||
{
|
||||
username,
|
||||
password,
|
||||
code,
|
||||
}: { username: string; password: string; code: string },
|
||||
req: any,
|
||||
) {
|
||||
const authInfo = this.getAuthInfo();
|
||||
const { isTwoFactorChecking, twoFactorSecret } = authInfo;
|
||||
if (!isTwoFactorChecking) {
|
||||
|
|
|
@ -167,7 +167,7 @@ run_concurrent() {
|
|||
run_designated() {
|
||||
local file_param="$1"
|
||||
local env_param="$2"
|
||||
local num_param="$3"
|
||||
local num_param=$(echo "$3" | perl -pe "s|.*$2 (.*)|\1|")
|
||||
if [[ ! $env_param ]] || [[ ! $num_param ]]; then
|
||||
echo -e "\n 缺少单独运行的参数 task xxx.js single Test 1"
|
||||
exit 1
|
||||
|
@ -268,7 +268,7 @@ main() {
|
|||
1)
|
||||
run_normal "$1"
|
||||
;;
|
||||
2 | 3 | 4)
|
||||
*)
|
||||
case $2 in
|
||||
now)
|
||||
run_normal "$1" "$2"
|
||||
|
@ -277,16 +277,13 @@ main() {
|
|||
run_concurrent "$1" "$3"
|
||||
;;
|
||||
desi)
|
||||
run_designated "$1" "$3" "$4"
|
||||
run_designated "$1" "$3" "$*"
|
||||
;;
|
||||
*)
|
||||
run_else "$@"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
run_else "$@"
|
||||
;;
|
||||
esac
|
||||
[[ -f $log_path ]] && cat $log_path
|
||||
elif [[ $# -eq 0 ]]; then
|
||||
|
|
14
typings.d.ts
vendored
14
typings.d.ts
vendored
|
@ -2,7 +2,15 @@ declare module '*.css';
|
|||
declare module '*.less';
|
||||
declare module '*.png';
|
||||
declare module '*.svg' {
|
||||
export function ReactComponent(props: React.SVGProps<SVGSVGElement>): React.ReactElement
|
||||
const url: string
|
||||
export default url
|
||||
export function ReactComponent(
|
||||
props: React.SVGProps<SVGSVGElement>,
|
||||
): React.ReactElement;
|
||||
const url: string;
|
||||
export default url;
|
||||
}
|
||||
|
||||
declare namespace Express {
|
||||
export interface Request {
|
||||
platform: 'desktop' | 'mobile';
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user