auth.service.js 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /**
  2. * Created by zhengguorong on 16/11/2.
  3. * 用户权限认证方法
  4. *
  5. * * Q&A
  6. * 为什么要使用composable-middleware,为了解决什么问题?
  7. * 他的作用是合并两个中间件,让其不需要在挂在在express实例上,例如expressJwt中间件是在执行后操作req对象,在req对象
  8. * 上加入user对象,但该中间件未提供回调方法,无法在验证后执行我们的代码,因此需要使用composable插件来完成两个中间件的
  9. * 合并.
  10. * 当然,你也可以像官方提供示例一样,router.get('/',jwtvalidate,function(req,res,next){req.user})获取结果,但是
  11. * 我的路由第三个参数主要执行数据库相关操作,不想引入验证逻辑,所以在第二个参数这里完成权限的认证.
  12. *
  13. */
  14. const jwt = require('jsonwebtoken')
  15. const expressJwt = require('express-jwt')
  16. const config = require('../config')
  17. const compose = require('composable-middleware')
  18. const User = require('../api/user/user.model')
  19. const UserController = require('../api/user/user.controller')
  20. const validateJwt = expressJwt({
  21. secret: config.secrets.session
  22. })
  23. /**
  24. * 验证用户是否有权限操作
  25. * @returns {function()}
  26. */
  27. module.exports.isAuthenticated = () => {
  28. return compose()
  29. .use(function (req, res, next) {
  30. // allow access_token to be passed through query parameter as well
  31. if (req.query && req.query.hasOwnProperty('access_token')) {
  32. req.headers.authorization = `Bearer ${req.query.access_token}`;
  33. }
  34. if(req.body && req.body.hasOwnProperty('access_token')) {
  35. req.headers.authorization = `Bearer ${req.body.access_token}`;
  36. }
  37. // IE11 forgets to set Authorization header sometimes. Pull from cookie instead.
  38. if (req.query && typeof req.headers.authorization === 'undefined') {
  39. req.headers.authorization = `Bearer ${req.cookies.token}`;
  40. }
  41. //验证是否服务端生成的token
  42. var token = req.headers.authorization.split('Bearer ')[1]
  43. UserController.findByToken(token).then((user) => {
  44. if (user) {
  45. //验证token是否过期
  46. validateJwt(req, res, next);
  47. }else{
  48. return res.status(401).end();
  49. }
  50. })
  51. })
  52. // Attach user to request
  53. .use(function (req, res, next) {
  54. User.findById(req.user._id).exec()
  55. .then(user => {
  56. if (!user) {
  57. return res.status(401).end();
  58. }
  59. req.user = user;
  60. next();
  61. })
  62. .catch(err => next(err));
  63. });
  64. }
  65. module.exports.hasRole = (roleRequired) => {
  66. if (!roleRequired) {
  67. throw new Error('必须输入身份名称');
  68. }
  69. return compose()
  70. .use(this.isAuthenticated())
  71. .use(function meetsRequirements(req, res, next) {
  72. if (config.userRoles.indexOf(req.user.role) >= config.userRoles.indexOf(roleRequired)) {
  73. return next();
  74. } else {
  75. return res.status(403).send('没有访问权限');
  76. }
  77. });
  78. }
  79. /**
  80. * 返回一个JWT TOKEN
  81. * @param id 用户ID
  82. * @param role 用户权限
  83. * @returns {*} JWT TOKEN
  84. */
  85. module.exports.signToken = (id, role) => {
  86. return jwt.sign({_id: id, role}, config.secrets.session, {
  87. expiresIn: 60 * 60 * 5
  88. })
  89. }