flightworker-atk-auth
Version:
## 中间件部署
160 lines (158 loc) • 4.47 kB
JavaScript
/**
* token插件
*/
const SETTING = Symbol('api#SETTING')
const $crypto = require('./crypto')
const $redis = require('./redis')
const co = require('co')
const EventEmitter = require('events')
/**
* 配置
* opt
* redis: {ip: xxx, port: xxx, timeout: xxx}
* staticToken // 默认可通过的token
* cookie: {name: xxx}
* serviceName: 'AMN'
* check: {'registerUrl': xxx, authUrlMap: []},
* registerAction // 注册函数
*/
exports = module.exports = class Core extends EventEmitter {
get config(){
return this[SETTING]
}
/**
* @param opt
*/
constructor(opt){
super()
this[SETTING] = opt
this.$redis = new $redis(opt.redis)
}
/**
* 远程注册token
* @param token
*/
// *_curlRegisterToken(token){}
/*setClientCookie(token, domain){
this.res.cookie(this.config.cookie.name, token, {
httpOnly: true,
path: '/',
domain,
maxAge: this.config.redis.timeout
})
}*/
/**
*
* @param req
* @param res
* @param next
*/
middleware(req, res){
const that = this
let domain = '.tuniu.com'
const r = /(\.[^:\/]+$)/
const next = token => this.emit('token', token)
if(r.test(req.hostname)){
domain = RegExp.$1
}
return co(function* (){
if(!req.session.token){
req.session.token = $crypto.key(16)
}
const name = req.session.token
let token = yield that.$redis.queryRegister(name)
let status = true
if(!token){
token = $crypto.key()
yield that.$redis.registerToken(name, token)
// yield that._curlRegisterToken(token)
}
// that.setClientCookie(token, domain)
next(token)
})
.catch(e => {
console.log(e.message)
let token = that[SETTING].staticToken
// that.setClientCookie(token, domain)
next(null)
})
}
// 注册本地token
registerLocalToken(req, res){
let that = this
return co(function* (){
let token = req.params.token
yield this.$redis.registerLocalToken(token, true)
res.status = 200;
res.end(JSON.stringify({
success: true,
data: null,
code: null,
msg: null
}))
}).catch(e => {
res.status = 504
res.end(JSON.stringify({
success: false,
data: null,
code: null,
msg: null
}))
})
}
//
throwAuthError(res, code){
return (send => {
if(!code){
return send
}else{
return send(code)
}
})(code => {
res.end(JSON.stringify({
success: false,
code,
data: null,
msg: null
}))
})
}
/**
* 检测是否是合法路由
* @param {*} req
* @param {*} res
* @param {*} next
*/
check(req, res){
let that = this
const throwAuthError = this.throwAuthError(res)
const next = status => this.emit('success', status !== false)
return co(function* (){
const isRegisterUrl = new RegExp(that.config.check.registerUrl)
if(isRegisterUrl.test(req.url)){
return yield that.registerLocalToken(req, res)
}
const authUrlMap = that.config.check.authUrlMap || []
const isCheckUrl = authUrlMap.map(url => {
const r = url instanceof RegExp && url || new RegExp(url)
return r.test(req.url)
}).filter(status => !!status).length > 0
if(!isCheckUrl){
return next()
}
let name = that.config.cookie.name
let token = req.cookies[name]
if(!token){
return throwAuthError()
}
const isAllow = yield that.$redis.queryRegister(token)
if(!isAllow){
return throwAuthError()
}
return next()
}).catch(e => {
next(false)
})
}
}