当前位置: 首页 > 后端技术 > Node.js

jwt_0

时间:2023-04-03 22:36:43 Node.js

1.jwt1.1。简介在之前的项目中,大部分网页都是通过session来判断用户是否有访问个别网页的权限,但是如果是SPA项目,前后端分离,客户端请求前端,所以数据不会被保存到会话中,那我该怎么办?对于这个问题,可以使用jwt来解决!JWT,也称为JSONWebToken(JWT),是目前最流行的跨域认证方案。JWT的组成:一个JWT其实就是一个字符串,它由三部分组成:头部(Header)、负载(Payload)和签名(signature)。生成加密字符串并将其发送给客户端。客户端将其保存在浏览器中(cookie/localstorage/sessionstorage)。当客户端请求敏感数据时,客户端必须携带加密后的字符串(token)给服务器端。服务器获取token值后,对信息进行解密比对。如果比较成功,则返回数据,如果不成功,则不返回数据。1.2、jsonwebtokennodejs中的jsonwebtoken提供了一套(jwt)加解密算法安装npmi-Sjsonwebtokennpmi-Sexpresscorsmongoose加解密vartoken=require("jsonwebtoken");//加密密钥varkey=token.sign(data,encryptedstring);//解密加密字符串解密还原密钥varsource=token.verify(key,encryptedstring);encryptedconstrouter=require('express').Router()constjwt=require('jsonwebtoken')//设置一个键值constsecretKeyjwt加解密需要的constsecretKey='afwefjwlefjlwjflewjjfew;jfwe;jfwe;jf;ejf;w'//登录成功后,保持注册人的状态,之前的方案使用session,现在我们前后端分离,使用jwt接口登录操作router.post('/login',(req,res)=>{let{username,password}=req.bodyres.send({code:0,msg:'ok',data:{//加密令牌:jwt.sign({id:1,username,//token过期时间一般设置为2小时,有的公司每天1个token,一周一个月//exp:Date.now()+7200*1000},secretKey)}})})decryptrouter.get('/users',(req,res)=>{consttoken=req.headers['token']res.send({code:0,msg:'ok',data:{id:1,name:'张三',token:jwt.verify(token,ssecretKey)}})})module.exports=router;2、接口编写2.1、restfulapi是一种软件架构风格和设计风格,不是标准,只是提供了一套设计原则和约束RestfulApi:面向资源解决问题降低开发的复杂度,提高系统的可扩展性2.2、规范①、协议:API与用户通信协议,一律使用http或https协议。②域名:API尽量部署在专用域名下,例如:http://api.demo.com③版本:API的版本号放在URL中,方便并且直观,例如http://api。demo.com/v1④、path在RESTful架构中,每个URL代表一个资源(resource),所以URL中不能有动词,只能有名词。示例:https://api.example.com/v1/users⑤、HTTP动词对资源的具体操作类型,用HTTP动词表示GET(SELECT):从服务器取出资源(一项或多项)。POST(CREATE):在服务器上创建一个新的资源。PUT/patch(UPDATE):更新服务器上的资源(客户端提供更改后的完整资源)。删除(DELETE):从服务器中删除一个资源。例如,以下方法用于操作和获取数据GET/zoos:列出所有动物园GET/zoos/ID:获取指定动物园的信息POST/zoos:创建一个新动物园PUT/zoos/ID:更新一个动物园的信息specifiedzoo(提供动物园的所有信息)DELETE/zoos/ID:删除一个动物园⑥、过滤信息如果记录很多,服务器无法全部返回给用户。API应提供参数并过滤返回的结果。例子:?limit=10:指定返回记录条数⑦、状态码服务器返回给用户的状态码和提示信息,常见的有以下几种(状态码对应的HTTP动词在方括号中)200OK-[GET]:服务器成功返回用户请求的数据,操作是幂等的。201CREATED-[POST/PUT/PATCH]:??用户成功创建或修改数据。202Accepted-[*]:表示请求已进入后台队列(异步任务)204NOCONTENT-[DELETE]:用户删除数据成功。400INVALIDREQUEST-[POST/PUT/PATCH]:??用户发送的请求有错误,服务器没有创建或修改数据。这个操作是幂等的。401Unauthorized-[*]:表示用户没有权限(错误的令牌、用户名、密码)。403Forbidden-[*]表示用户已获得授权(与401错误相反),但访问被禁止。404NOTFOUND-[*]:用户发送的请求是针对一条不存在的记录,服务器没有进行任何操作,是幂等的。406NotAcceptable-[GET]:用户请求的格式不可用(比如用户请求JSON格式,但只请求XML格式)。410Gone-[GET]:用户请求的资源被永久删除,不会再次获取。422无法处理的实体-[POST/PUT/PATCH]创建对象时发生验证错误。500INTERNALSERVERERROR-[*]:服务器发生错误,用户将无法确定请求是否成功。⑧.返回结果对于不同的操作,服务器返回给用户的结果应符合以下规范GET/collection:返回资源对象列表数组GET/collection/resource:返回单个资源对象POST/collection:返回一个新的资源对象生成的资源对象PUT/collection/resource:返回一个完整的资源对象DELETE/collection/resource:返回一个空文档3.构建项目3.2.前端项目构建使用webpack进行前端项目工程构建package.json{"name":"project","version":"1.0.0","description":"","main":"index.js","scripts":{"serve":"webpack-dev-server","build":"webpack"},"keywords":[],"author":"","license":"ISC","devDependencies":{"@babel/core":"^7.14.3","@babel/preset-env":"^7.14.2","art-template":"^4.13.2","art-template-loader":"^1.4.3","babel-loader":"^8.2.2","clean-webpack-plugin":"^4.0.0-alpha.0","copy-webpack-plugin":"^6.4.1","core-js":"^3.13.0","css-loader":"^5.2.6","file-loader":"^6.2.0","html-loader":"^1.3.2","html-webpack-plugin":"^4.5.2","style-loader":"^2.0.0","ts-loader":"^6.2.2","typescript":"^4.3.2","url-loader":"^4.1.1","webpack":"^4.46.0","webpack-cli":"^3.3.12","webpack-dev-server":"^3.11.2"},"dependencies":{"jquery":"^3.6.0"}}webpack.config.jsconstpath=require('path')//webpack插件,帮助webpack打包生成,创建一个index.html文件constHtmlWebpackPlugin=require('html-webpack-plugin')//删除打包的dist目录const{CleanWebpackPlugin}=require('clean-webpack-plugin')//静态资源拷贝constCopyPlugin=require('copy-webpack-plugin')module.exports={//启用模式,生产或开发模式:'development',//开发时配置开发工具配置source-map函数:代码有错,可以帮我们定位到src目录下的程序。devtool:'source-map',//指定入口文件//stringentry:'./src/main.js',//exportoutput:{//打包生成的文件路径的绝对地址path:path.resolve('dist'),//打包生成后主入口js文件filename:'[name].[hash:8].js'},resolve:{alias:{'@':path.resolve('src')},extensions:['.js','.json','.art']},//loadermodule:{//rules:[//Processcss{//正则匹配loader解析文件扩展名测试:/\.css$/i,//Loader执行顺序//一行写的执行顺序:从右到左,多行写的:从下往上执行use:["style-loader","css-loader"]},//图片处理{test:/\.(png|jpeg|jpg|gif)$/i,use:[{loader:'url-loader',options:{//如果图片小于8kb,会被base64处理limit:1*1024,name:'images/[name].[ext]',publicPath:'/'}}]},//html中的图像处理{test:/\.html$/,loader:['html-loader']},//js兼容处理{test:/\.js$/,use:[{loader:'babel-loader',options:{presets:[['@babel/preset-env',{//按需加载useBuiltIns:'usage',//指定core-js版本corejs:3,//兼容哪个版本的浏览器targets:{chrome:'75'}}]]}}]},//模板引擎解释{test:/\.art$/,use:["art-template-loader"]}]},//插件plugins:[newCleanWebpackPlugin(),newHtmlWebpackPlugin({//templatetemplate:path.resolve('public/index.html')}),//复制静态资源——直接复制,不做任何处理newCopyPlugin({patterns:[{//sourcefrom:path.resolve('public/favicon.ico'),//targetto:path.resolve('dist/favicon.ico')}]})],devServer:{port:3000,//显示编辑打包进度progress:true,//安静模式,无显示打包信息quiet:true,//proxyproxy:{'/api':{target:'https://api.iynn.cn/film',changeOrigin:true,pathRewrite:{//'^/api':''}}}}}tsconfig.json{"compilerOptions":{"target":"es5","module":"commonjs","strict":true}}前端路由使用第三方路由模块SMERouter是用express风格写的,前端路由库,所以api有点类似express。npmi-Ssme-routerhttps://sme-fe.github.io/website-router/zh/basic.html#修复路由npmi-Swucode-router