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.效果圖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM