总体思路
token两个作用 1鉴权(鉴定是否有这个权限) 2.进行简单的数据交互
客户端登录—> 成功(服务器接收数据) —>服务器根据密钥生成token(2出明文和一处密钥)像一个门票—>发送客户端
token —>客户端储存; 客户端再次登录时获取到储存的token —> 请求头部携带token —>发送到服务器
服务端—> 验证通过—> 返回数据
验证不通过—> 返回401
1.ajax发送信息
2.服务端接收验证 如果 验证成功签发密钥 token
参数1:传递的信息 2:当前token密钥(一般都在后端人员手里)3:时效
const token = jwt.sign({
id:1 //字段用来描述用户信息的
},“mytoken”,{expiresIn:“2h”});
3.发送前端储存秘钥 设置请求头部属性 固定 Bearer拼接一定要带空格
xhr.setRequestHeader(“Authorization”,“Bearer “+ token);
4.再次登录整体打包发送
5.服务器判断秘钥
router.post(”/apiCheck”,koaJwt({secret:“mytoken”}),ctx=>{
ctx.body = {
name:“我是神秘接口来的”
}
router.post("/apiCheck",koaJwt({secret:"mytoken"}),ctx=>{
ctx.body = {
name:"我是神秘接口来的"
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="css/login.css" />
<title>Document</title>
</head>
<body>
<div class="loginContainer">
<h1>登录</h1>
<!--设置false后不跳转了 -->
<form action="/checkUser" method="post" onsubmit="return false">姓名:
<input class="inputStyle" id="username" type="text" name="username" />
<!-- <div class="exchange">用户名错误</div> -->
<br />密码:
<input class="inputStyle" id="pwd" type="password" name="pwd" /><br />
<input class="loginStyle" type="submit" value="登录" />
<button class="btn">点击请求,需要认证的接口</button>
</form>
</div>
<script>
document.querySelector(".loginStyle").onclick = function(){
let username = document.querySelector("#username").value;//获取用户名
let pwd = document.querySelector("#pwd").value;//value框中的密码
let xhr = new XMLHttpRequest();
xhr.open("post","/checkUser",true)
// 设置头部信息
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
xhr.onload = function(){
console.log(xhr.responseText)
// 后端判断完用户名和密码 返回数据
let token = JSON.parse(xhr.responseText).token;//
// 后端返回的密钥信息 头部信息 字段 密码 官网jwt.io
// eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 头部信息 明文
// .eyJfaWQiOjEsImlhdCI6MTU4Njg0MjI3NiwiZXhwIjoxNTg2ODQ5NDc2fQ 字段内容明文
// .K11fy9anFARL6U-_77G43smkcqWTP7a7IreXUIDPnQs 密码 密文
localStorage.setItem("token",token); //储存后端返回的token
// 用户名密码正确 按需跳转页面登录
}
let data = `username=${username}&pwd=${pwd}`
xhr.send(data) //把用户名和密码发送到服务器
// 点击触发 需要认证的数据:头部携带token 请求接口
document.querySelector(".btn").onclick = function(){
let xhr =new XMLHttpRequest();
xhr.open("post","/apiCheck",true)
// 获取上面设置好的token
let token = localStorage.getItem("token");
if(token){ //如果有token q请求头部属性 固定 Bearer拼接一定要带空格
xhr.setRequestHeader("Authorization","Bearer "+ token);
}
xhr.onload = function(){
console.log(xhr.responseText);
}
xhr.send()
}
}
</script>
</body>
</html>
服务端
const Koa = require("koa");
const Router = require("koa-router");
const KoaBody = require("koa-body");
const sta = require("koa-static");
// jwt 和 koaJwt都不需要app.use()来加载直接使用
const jwt = require("jsonwebtoken") //签发token
const koaJwt = require("koa-jwt") //验证token
let app = new Koa();
let router = new Router();
app.use(KoaBody());
app.use(sta(__dirname+"/static"));
router.get("/login",ctx=>{
ctx.body = "jwt"
})
// 登录验证的接口
router.post("/checkUser",ctx=>{
//前段设置头部 这接收用户名和密码输出 是个对象
console.log(ctx.request.body);
let {username,pwd} = ctx.request.body;
let info;
// 判断用户名和密码是否一致
if(username === "张三" && pwd === "123"){
// 如果 验证成功签发密钥 token
// 参数1:传递的信息 2:当前token密钥(一般都在后端人员手里)3:时效
const token = jwt.sign({
_id:1 //字段用来描述用户信息的
},"mytoken",{expiresIn:"2h"});
//
info = {
message:"正确",
status:1,
token // 打包一块发送到前端
}
}else{
info = {
message:"错误", //提示信息
status:0,
}
}
ctx.body = info; // 判断后返还到客户端
})
// 需要token认证的接口 单独写个录路由 访问的时候得带上token值认证
// 也就是说当页面带着token认证的时候,通过后直接就能登录
// 签发的密码和前段发过进行对比验证
router.post("/apiCheck",koaJwt({secret:"mytoken"}),ctx=>{
ctx.body = {
name:"我是神秘接口来的"
}
})
app.use(router.routes())
app.listen(8888)