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