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