• koa 项目实战(九)passport验证token


    1.安装模块

    npm install koa-passport -D
    
    npm install passport-jwt -D

    2.解析token

    根目录/config/passport.js

    const JwtStrategy = require('passport-jwt').Strategy,
      ExtractJwt = require('passport-jwt').ExtractJwt;
    const keys = require('../config/keys');
    const opts = {};
    opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
    opts.secretOrKey = keys.secretOrkey;
    const mongoose = require('mongoose');
    const User = mongoose.model('users');
    
    module.exports = passport => {
      passport.use(new JwtStrategy(opts, async function (jwt_payload, done) {
        // console.log(jwt_payload);
        const user = await User.findById(jwt_payload.id);
        if (user) {
          return done(null, user);
        } else {
          return done(null, false);
        }
      }));
    };

    3.引用

    根目录/app.js

    const passport = require('koa-passport');
    ...
    
    // 初始化 passport
    app.use(passport.initialize());
    app.use(passport.session());
    
    // 回调到config文件中 passport.js
    require('./config/passport')(passport);

    4.获取用户信息接口

    /**
     * @route GET api/users/current
     * @desc  用户信息接口地址 返回用户信息
     * @access 接口是私密的
     */
    router.get(
      '/current',
      passport.authenticate('jwt', { session: false }),
      async ctx => {
        ctx.body = {
          id: ctx.state.user.id,
          name: ctx.state.user.name,
          email: ctx.state.user.email,
          avatar: ctx.state.user.avatar
        };
      }
    );

    根目录/routes/api/users.js

    const Router = require('koa-router');
    const router = new Router();
    const bcrypt = require('bcryptjs');
    const gravatar = require('gravatar');
    const tools = require('../../config/tools');
    const jwt = require('jsonwebtoken');
    const keys = require('../../config/keys');
    const passport = require('koa-passport');
    
    // 引入User
    const User = require('../../models/User');
    
    /**
     * @route GET api/users/test
     * @desc 测试接口地址
     * @access 接口是公开的
     */
    router.get('/test', async ctx => {
      ctx.status = 200;
      ctx.body = { msg: 'users works...' };
    });
    
    /**
     * @route POST api/users/register
     * @desc 注册接口地址
     * @access 接口是公开的
     */
    router.post('/register', async ctx => {
      // console.log(ctx.request.body);
    
      // 通过邮箱判读是否注册过
      const findResult = await User.find({ email: ctx.request.body.email });
      // console.log(findResult);
      if (findResult.length > 0) {
        ctx.status = 500;
        ctx.body = { email: '邮箱已被占用 ' };
      } else {
        const avatar = gravatar.url(ctx.request.body.email, { s: '200', r: 'pg', d: 'mm' });
        const newUser = new User({
          name: ctx.request.body.name,
          email: ctx.request.body.email,
          avatar,
          password: tools.enbcrypt(ctx.request.body.password)
        });
    
        // console.log(newUser);
        // 存储到数据库
        await newUser.save().then(user => {
          ctx.body = user;
        }).catch(err => {
          console.log(err);
        });
    
        // 返回json数据
        ctx.body = newUser;
      }
    });
    
    /**
     * @route POST api/users/login
     * @desc 登录接口地址
     * @access 接口是公开的
     */
    router.post('/login', async ctx => {
      // 查询
      const findResult = await User.find({ email: ctx.request.body.email });
      const user = findResult[0];
      const password = ctx.request.body.password;
    
      // 判断差没查到
      if (findResult.length == 0) {
        ctx.status = 404;
        ctx.body = { email: '用户不存在!' };
      } else {
        // 查到后 验证密码
        var result = await bcrypt.compareSync(password, user.password);
    
        // 校验通过
        if (result) {
          // 返回token
          const payload = { id: user.id, name: user.name, avatar: user.avatar };
          const token = jwt.sign(payload, keys.secretOrkey, { expiresIn: 3600 });
    
          ctx.status = 200;
          ctx.body = { success: true, token: 'Bearer ' + token };
        } else {
          ctx.status = 400;
          ctx.body = { password: '密码错误!' };
        }
      }
    })
    
    /**
     * @route GET api/users/current
     * @desc  用户信息接口地址 返回用户信息
     * @access 接口是私密的
     */
    router.get(
      '/current',
      passport.authenticate('jwt', { session: false }),
      async ctx => {
        ctx.body = {
          id: ctx.state.user.id,
          name: ctx.state.user.name,
          email: ctx.state.user.email,
          avatar: ctx.state.user.avatar
        };
      }
    );
    
    module.exports = router.routes();

    5.效果图

  • 相关阅读:
    linux 环境变量 ($PATH)
    read()、write()返回 Input/output error, Device or resource busy解决
    初次尝试一个注册表
    CSS定位
    CSS中颜色代码和单位
    DOM和BOM
    java代码中获取classpath路径
    黑盒测试与白盒测试相比,哪个更难
    LoadRunner11遇到问题及解决办法
    Linux下修改日期和时间
  • 原文地址:https://www.cnblogs.com/crazycode2/p/11070887.html
Copyright © 2020-2023  润新知