koa2+redis+jwt token验证,简单注册登录
首先新建文件夹命名koa-server,npm init,相关包的安装就不说了,这是我的package.json

新建index.js文件,编码如下,config全局配置不用管,redis是一个简单的get和set操作的封装,也不用管
const bodyParser = require("koa-bodyParser");
const Koa = require("koa");
const koaStatic = require("koa-static");
const path = require("path");
const cors = require("koa2-cors");
const koaJwt = require('koa-jwt');
// const
const token = require("./model/paytoken")
const constroller = require("./controller");
const config = require("./model/config");
const db = require("./model/redis");
const app = new Koa();
//全局配置
global.config = config;
global.db = db;
global.secret = "tokensecret";
//设置静态目录
app.use(koaStatic(path.resolve(__dirname,"./public")));
//跨域
app.use(cors());
//post 参数解析
app.use(bodyParser());
//token验证是否过期或失效
app.use(token);
//容错处理
app.use((ctx,next)=>{
return next().catch((error)=>{
if(error.status === 401){
ctx.status = 401;
ctx.body = {
code:-1,
msg:"token error 401"
}
}
else{
throw error;
}
});
});
//token过滤规则
app.use(koaJwt({secret:global.secret}).unless({
path:[
/^\/api\/login/,
/^\/api\/register/,
/^((?!\/api).)*$/
]
}));
//导入controller middleware
app.use(constroller());
//启动
app.listen(config.port);
console.log(`server start at 3000`);
其中paytoken是token的解析与验证,在这里可以获取加密的相关信息,如userid等,这里保存到ctx上下文,保证是本次请求,命名token_data
const jwt = require('jsonwebtoken');
async function verify(ctx,next){
let url = ctx.request.url;
let authorization = ctx.request.headers["authorization"];
if(authorization){
let token = authorization.split(" ")[1];
let payload = jwt.verify(token,global.secret,(error,decoded)=>{
if(error){
ctx.body = {
status:-1,
msg:"登陆失效"
};
}
else{
ctx.token_data = decoded;
return next();
}
});
}
else{
return next();
}
}
module.exports = verify;
controller是路由控制,主要用于路由自动解析,原理是扫描controllers文件夹下的所有js文件,同时对其require导出,规则是必须导出前缀为"PSOT "或"GET "的路由,用于api接口的访问
const fs = require("fs");
function addMapping(router,mapping){
for(let url in mapping){
if(url.startsWith('GET')){
//如果url类似get xxx
let path = url.substring(4);
router.get(path,mapping[url]);
}
else if(url.startsWith("POST")){
//如果url 类似post xxx
let path = url.substring(5);
router.post(path,mapping[url]);
}
else{
console.log(`invalid URL:${url}`);
}
}
}
function addControllers(router,dir){
let files = fs.readdirSync(__dirname + "/" + dir);
//过滤js文件
let js_files = files.filter((f)=>{
return f.endsWith(".js");
});
//处理每个js文件
for(let f of js_files){
let mapping = require(__dirname + '/controllers/' + f);
addMapping(router,mapping);
}
}
module.exports = function(dir){
let controllers_dir = dir || "controllers";
let router = require("koa-router")();
addControllers(router,controllers_dir);
return router.routes();
}
controllers文件夹下新建sign.js文件,处理login和register
const jwt = require('jsonwebtoken');
const db = global.db;
//注册路由
let register_func = async (ctx,next)=>{
let name = ctx.request.body.userName;
let password = ctx.request.body.password;
let userdata = {name,password};
let body;
if(!name || !password){
body = {
code:-1,
msg:"用户名或密码不能为空"
}
}
else if(name.length < 4){
body = {
code:-1,
msg:"用户名长度必须大于等于4"
}
}
else if(password.length < 8){
body = {
code:-1,
msg:"密码至少为8位"
}
}
else{
let data = await db.getKey(name);
if(data){
body = {
code:-1,
msg:"用户名重复",
}
}
else{
let result = await db.setKey(name,JSON.stringify(userdata));
if(result == "OK"){
body = {
code:0,
msg:"注册成功",
token:jwt.sign(userdata,global.secret,{expiresIn:'4h'})
}
}
else{
body = {
code:-1,
msg:"注册失败,原因未知"
}
}
}
}
ctx.body = body;
}
//登录路由
let login_func = async (ctx,next)=>{
let name = ctx.request.body.userName || "";
let password = ctx.request.body.password || "";
if(!name || !password){
ctx.body = {
code:-1,
msg:"用户名或密码错误"
}
}
else{
let result = await db.getKey(name);
let body;
if(!result){
body = {
code:-1,
msg:"用户不存在"
}
}
else{
let data = JSON.parse(result);
if(data.password === password){
body = {
code:0,
msg:"登录成功",
token:jwt.sign({name,password},global.secret,{expiresIn:'4h'})
}
}
else{
body = {
code:-1,
msg:"密码错误"
}
}
}
ctx.body = body;
}
}
module.exports = {
"POST /api/login":login_func,
"POST /api/register":register_func
}
其中生成签名token代码如下
jwt.sign(userdata,global.secret,{expiresIn:'4h'})
接下来post请求/api/login,传入参数成功则生成token返回给客户端,否则失败,注意redis数据库必须有数据
或者/api/register注册,存一个新的
验证token只需要新建一个js,比如排行榜rank.js,如果前端没有在header中设置token或者token设置为不存在的,则会返回401,token error
前端附加token必须是(以vue、axios为例)

大胆尝试是进步的主力,如果连尝试都不去,那什么也做不成,就像有钱人的儿子都很有钱一样,你穷并不是因为你代码写的不好,而是因为世界是不和平的,所以活出自己吧!
koa2+redis+jwt token验证,简单注册登录的更多相关文章
- Java带token验证的注册登录
http://blog.csdn.net/huqingpeng321/article/details/52900550 http://blog.csdn.net/l18710006370/articl ...
- 使用Flask开发简单接口(4)--借助Redis实现token验证
前言 在之前我们已开发了几个接口,并且可以正常使用,那么今天我们将继续完善一下.我们注意到之前的接口,都是不需要进行任何验证就可以使用的,其实我们可以使用 token ,比如设置在修改或删除用户信息的 ...
- Spring Boot + Security + JWT 实现Token验证+多Provider——登录系统
首先呢就是需求: 1.账号.密码进行第一次登录,获得token,之后的每次请求都在请求头里加上这个token就不用带账号.密码或是session了. 2.用户有两种类型,具体表现在数据库中存用户信息时 ...
- SpringSecurityOAuth使用JWT Token实现SSO单点登录
⒈认证服务器 1.添加pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti ...
- jwt Token验证与解析
网上似乎没有相关代码 贴上一段Token的解析认证 [TestMethod] public void TestMethod1() { string Token = "eyJhbGciOiJI ...
- koa2+mysql+vue实现用户注册、登录、token验证
说明: node.js提供接口,vue展现页面,前后端分离,出于编辑器功能和编辑习惯,vue用HbuilderX,node.js用VScode.(PS:仅作为学习笔记,如有不当之处欢迎指出,在此先谢为 ...
- jwt token and shiro
openapi可以完全开放访问,也可以使用jwt token进行简单的认证,还可以使用shiro支持更细致的权限管理. handler.yml配置了security和shiro两个handler: s ...
- asp.net core使用identity+jwt保护你的webapi(二)——获取jwt token
前言 上一篇已经介绍了identity在web api中的基本配置,本篇来完成用户的注册,登录,获取jwt token. 开始 开始之前先配置一下jwt相关服务. 配置JWT 首先NuGet安装包: ...
- Node.js原生及Express方法实现注册登录原理
由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...
随机推荐
- A.Who is better?(The Preliminary Contest for ICPC Asia Xuzhou 2019)
https://nanti.jisuanke.com/t/41383 解: 斐波那契博弈+中国剩余定理. #include <bits/stdc++.h> using namespace ...
- GitHub访问及git工具克隆慢问题解决
一.查询合适的DNS服务器 1.站长工具DNS查询服务器 github.com github.global.ssl.fastly.net 2.选择TTL值最小的记录,记录下对应服务器IP地址 例如 g ...
- paramiko-ssh-秘钥认证实例
import paramiko private_key = paramiko.RSAKey.from_private_key_file('id_rsa.txt') #创建ssh对象 ssh =para ...
- Java 概述和编程基础
First of all,Java概述: 类是Java程序设计的基石和基本单元: main()方法是程序的入口,它是共有的.静态的,参数String[] args表示一个字符串数组可以传入该程序,用来 ...
- id和class的区别
id和class是定义css样式用到的,不同的是定义样式时的写法不一样,使用id选择样式时,定义的格式为 #main{width:20px;} ,使用class时用到的是 .main{width:20 ...
- 弹窗插件 layer
官方网站 http://layer.layui.com/ Github 地址 https://github.com/sentsin/layer //在这里面输入任何合法的js语句 layer.open ...
- 你不知道的css各类布局(一)之固定布局、静态布局
前言 当为大量用户设计网站时,设计人员必须考虑到访问者的差异: 屏幕分辨率, 浏览器的选择, 是否在浏览器最大化状态, 浏览器的额外工具栏的开启(历史记录,书签等), 操作系统和硬件. 我们知道css ...
- Win32 编程
1.ShowWindow(SW_SHOWNORMAL) 参数 : SW_HIDE激活另外一个窗口,当前窗口就跑到那个窗口后面了SW_MAXIMIZE显示的窗口是最大化的SW_MINIMIZE显示的窗 ...
- 初识 vue------简单介绍
/** vue 作者:尤雨溪 类型:MVVM 准确的来说是MV框架 为什么要学习vue 1.传统的项目是通过操作dom元素来修 ...
- Golang新开发者要注意的陷阱和常见错误
转自:http://colobu.com/2015/09/07/gotchas-and-common-mistakes-in-go-golang/ 目录 [−] 初级 开大括号不能放在单独的一行 未使 ...