Koa初体验之RSA256+jsonwebtoken的JWT
项目介绍
使用RSA256加密实现jwt鉴权最终获取token
项目开始
1.安装依赖
npm install jsonwebtoken
2.获取RSA公钥和私钥
(因系统不同命令有所不同 ,我这边是mac栗子)
openssl
genrsa -out rsa_private_key.pem 1024
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
完成后生成两个文件(rsa_private_key.pem 与 rsa_public_key.pem)
当然这块也可以修改文件名,我修改成了我喜欢的 ,并统一放到了文件夹下,如图所示:
代码实现
1.设置登录的路由
koa.use(koaRoute.post('/sessions', controller.post.bind(controller)))
2.Controller层SessionsController.js
//登录post接口
post (ctx) {
//首先判断headers不能为空
if (ctx.headers.authorization === undefined || ctx.headers.authorization === null || ctx.headers.authorization === '') {
ctx.throw(400, 'Authorization header must be provided!')
} else {
return this._handleAuthorization(ctx)
}
}
_handleAuthorization (ctx) {
const [type] = ctx.headers.authorization.split(' ')
if (type.toLowerCase() === 'basic') {
return this._handleBasicAuthentication(ctx)
} else {
ctx.throw(400, 'Invalid authentication type!')
}
}
_handleBasicAuthentication (ctx) {
const [, base64String] = ctx.headers.authorization.split(' ')
console.log(base64String)
const [username, password] = Buffer.from(base64String, 'base64').toString().split(':')
console.log(username + password)
return this.getUserByCredentials(username, password)
.then(user => this._handleUser(ctx, user))
.then(jwt => this._respondWithJwt(ctx, jwt))
}
async getUserByCredentials (username, password) {
//密码加密
const passwordHash = crypto.createHash('sha256')
.update(password)
.digest('hex')
console.log(passwordHash)
const user = await this._getUserByUsername(username)
console.log(user)
if (user === null) {
return null
} else {
if (user.passwordHash === passwordHash) {
return user
} else {
return null
}
}
}
_getUserByUsername (username) {
//查询user表用户名和传入的用户名是否一样
return this._User.findOne({
where: { userName: username }
})
}
_handleUser (ctx, user) {
if (user === null) {
ctx.throw(400, 'Invalid user!')
} else {
const payload = {
usr: user.id,
role: user.role,
name: user.name
}
console.log(payload)
return this._generateJwt(payload)
}
}
// jwt.sign(payload, secretOrPrivateKey, [options, callback])
// 第一个是token载体,放一些需要存放在token里的内容,我这里希望token传递userId,role,name
// 第二个是密钥,可以简单的输入string作为密钥,也可以采用加密算法,例如我现在用的RSA256
// 第三个是option,因为jsonwebtoken加密方式默认是RS256,所以如果用其他加密方式需要在option的algorithm中进行申明,以及其他一些参数
_generateJwt (payload) {
const minutes = 432000
const privateKey = fs.readFileSync('rsaKeys/jwtRS256.key')
const options = { algorithm: 'RS256', expiresIn: minutes * 60 }
return jwt.sign(payload, privateKey, options)
}
_respondWithJwt (ctx, jwt) {
ctx.status = 201
ctx.body = jwt
return ctx
}
}
3.入口文件引入(app.js)
const jwt = require('koa-jwt')
const fs = require("fs")
const publicKey = fs.readFileSync('./rsaKeys/jwtRS256.key.pub')//引用公钥
app.use(jwt({
secret: publicKey,
key:'token'
}).unless({
path: ['/sessions']
}));
测试登录接口
1.插件测试登录接口,返回token
我这里用的是谷歌自带的插件测试接口
headers 里Authorization输入登录的用户名密码
设置这里就结束里 触发send按钮 就返回得到token
2.测试其他接口加上token访问
不带token,接口返回结果如图(401)
带token接口返回结果如图