const jwt = require('jsonwebtoken') const router = require('express').Router() const { ok, fail } = require('../lib/response') const { signUser, readBearer } = require('../lib/auth') const { code2Session } = require('../lib/wechat') const config = require('../config') const userDao = require('../dao/user.dao') const logDao = require('../dao/log.dao') const wrap = fn => (req, res, next) => fn(req, res, next).catch(next) router.post('/auth/login', wrap(async (req, res) => { const session = await code2Session(req.body.code || '') let user = await userDao.findByOpenid(session.openid) if (!user) { const result = await userDao.create(session.openid) user = await userDao.findById(result.insertId) await logDao.write({ user_id: user.user_id, action: 'user_register', detail: '新用户注册', ip: req.ip }) } const token = signUser(user) await logDao.write({ user_id: user.user_id, action: 'user_login', detail: '用户登录', ip: req.ip }) res.json(ok({ token, user_id: String(user.user_id), user_info: { user_id: String(user.user_id), nickname: user.nickname || '用户' + String(user.user_id), avatar: user.avatar || '', phone: user.phone || '', gender: user.gender || 0 }, expires_in: 604800 })) })) router.post('/auth/refresh', wrap(async (req, res) => { const token = readBearer(req.headers) if (!token) return res.json(fail(1001, 'token_expired')) let payload try { payload = jwt.verify(token, config.jwt.secret) } catch (err) { if (err.name === 'TokenExpiredError') { try { payload = jwt.verify(token, config.jwt.secret, { ignoreExpiration: true }) } catch (_) { return res.json(fail(1001, 'token_expired')) } const now = Math.floor(Date.now() / 1000) const gracePeriod = 3 * 24 * 60 * 60 if (now - payload.exp > gracePeriod) { return res.json(fail(1001, 'token_expired')) } } else { return res.json(fail(1001, 'token_expired')) } } if (payload.type !== 'user') return res.json(fail(1001, 'token_expired')) const now = Math.floor(Date.now() / 1000) const sevenDays = 7 * 24 * 60 * 60 if (payload.exp && payload.exp > now && (payload.exp - now) > sevenDays) { return res.json(ok({ token, expires_in: payload.exp - now })) } const user = await userDao.findById(payload.user_id) if (!user) return res.json(fail(1001, 'token_expired')) const newToken = signUser(user) res.json(ok({ token: newToken, expires_in: 604800 })) })) module.exports = router