❤Node11-登录人token信息接口
上一章我们已经从登录部分拿到了用户的登录jwt返回的token信息,接下来我们就通过token来换取用户信息 这里我们可以将其理解为一种加密以及解密的思想来思考这个jwt和token的关系,token就是一个加密的字符串,而jwt就是那把钥匙。
1、解析 JWT字符串 还原为JSON对象
客户端每次在访问那些有权限接口的时候,都需要主动通过请求头中的 **Authorization**
字段,将 Token 字符串发送到服务器进行身份认证。 此时,服务器可以通过 express-jwt这个中间件,自动将客户端发送过来的 Token 解析还原成 JSON 对象: token解析如下:
app.use(
expressJWT.expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
// path: [/^\/api\//],
path: [
'/',
'/api/login',
'/api/register',
'/api/resetPwd'
]
})
);
这个时候我们请求的接口里面携带一下刚刚的token然后访问一下试试
js
axios({
method: 'get',
url: api,
headers: {
'Authorization': 'Bearer '+localStorage.getItem("login"),
'Content-Type': 'application/json;charset=utf-8',
'Custom-Header': 'custom-value'
},
params: params,
})
.then(res => {
console.log(res.data);
if (res.status == 200) {
// console.log(res, 'res');
tableData.value = res.data.data;
totalvalue.value = res.data.total;
}
})
.catch(error => {
console.error(error);
});
可以看到,这个时候我们的接口请求参数已经完全没问题了!
2、 获取用户信息(接口)
当 express-jwt 这个中间件配置成功之后,即可在那些有权限的接口中,使用 req.user 对象,来访问从 JWT 字符串中解析出来的用户信息了,示例代码如下:
js
// 这是一个有权限的api接口
app.get('/api/getInfo', (req, res) => {
console.log(req.user);
res.send({
status: 200,
message: 'success',
data: req.user,
})
})
从上面我们注册时候的接口可以看到,我们当时候注册了一个用户的username
返回的信息如下:
js
req.auth信息如下:
{ username: 'admin', iat: 1713773255, exp: 1713780455 }
返回的信息内容如下:
js
- `username: 'admin'`: 这是 JWT 中存储的用户名信息,指示该令牌是以管理员身份签发的或者与管理员相关联的。
- `iat: 1713773255`: 这是 JWT 的 "issued at"(签发时间)字段,表示 JWT 的签发时间。它是一个 Unix 时间戳,表示从 1970 年 1 月 1 日 00:00:00 UTC 到签发 JWT 的时间经过的秒数。
- `exp: 1713780455`: 这是 JWT 的 "expiration time"(过期时间)字段,表示 JWT 的过期时间。也是一个 Unix 时间戳,表示 JWT 过期的时间点。在这个时间点之后,JWT 将不再被认为是有效的,需要重新获取新的 JWT。
从这个返回信息的签发时间,我们可以思考一下可以起到什么样的用途呢:
3、查询我们数据用户信息
通过我们的用户接口返回的username参数去查询我们数据用户信息
js
app.get('/api/getInfo', (req, res) => {
// 查询用户详情接口
const values=[req.auth.username];
let query = 'SELECT * FROM user WHERE username = ?';
connectionpool.query(query, values, (err, results) => {
if (err) {
console.error('Error querying database:', err);
res.status(500).json({ error: '用户不存在!' });
return;
}else{
res.json({
code: '200',
data: results,
});
}
});
})
最后我们查到的数据库信息如下: 可以看到我们查出来的其实是一个数组,这个时候我们可以优化一下,当查询出来的数据是空数据的时候,默认给个赋值,当含有数据的时候,拿数组的第一项数据 优化结果
js
data: results?.length>0? results[0] : {},
4、测试使用用户信息接口
接下来我们找个网页利用axios(自己把token给放进去哦记得!)尝试请求一下看是否可以获取对应的用户信息
js
// 获取用户信息
function getUserinfo() {
let api = "http://localhost:8888/api/getInfo";
axios({
method: 'get',
url: api,
headers: {
'Authorization': 'Bearer '+localStorage.getItem("login"),
'Content-Type': 'application/json;charset=utf-8',
'Custom-Header': 'custom-value'
},
})
.then(res => {
console.log(res.data);
if (res.status == 200) {
console.log(res, 'res-获取用户信息');
}
})
.catch(error => {
console.error(error);
});
}
在我们自己封装的项目之中进行封装一下
js
// 获取用户信息
export function getInfo () {
return request({
url: '/api/getInfo',
method: 'get',
})
}
import React,{ useEffect } from "react";
import { getInfo } from '@/api/common/comon';
// 获取用户信息
const getUserInfo = () => {
console.log('获取用户信息');
getInfo().then(res => {
console.log(res,'获取用户信息');
setUserinfo(res.data);
})
}
useEffect(() => {
console.log('useEffect-home');
getUserInfo();
},[])
查询没问题,可以获取用户的信息!
5、优化用户信息接口
👍 time(2024-8-10)
优化提示信息
之前我们简单实现了我们的用户信息接口,但是在使用token换取信息的过程之中,很多次都是直接500,但是找不到其中的原因 接下来我们完善优化一下我们的用户信息接口
- 授权信息提示的完善
js
if (!req.auth || !req.auth.username) {
return res.status(401).send({
code: 401,
message: '未认证用户或缺少用户名!',
});
}
- 优化一下信息提示部分
js
if (err) {
console.error('Error querying database:', err);
return res.status(500).send({
code: 500,
message: '数据库查询错误!',
});
}
if (results.length === 0) {
return res.status(404).send({
code: 404,
message: '用户不存在!',
});
}
res.send({
code: 200,
data: results[0],
message: '欢迎你的访问!',
});
👍 time(2024-8-14)
处理问题
今天访问接口,一直提示我这个问题
js
{code: 500, message: "服务器错误!"}
然后我找了一遍可能是链接过程的问题,之前我们对于接口500的时候进行了一个拦截,我们打印出来看看
js
// 接口错误的封装---拦截部分
app.use((err, req, res, next) => {
// 如果错误是由token解析失败导致的
if (err.name === 'UnauthorizedError') {
return res.send({
code: 401,
message: '登录过期,请重新登录!'
})
}
console.log('其他原因导致的错误!',err);
// 如果是其他位置原因导致的错误
res.send({
code: 500,
message: '服务器错误!'
})
next()
})
输出以后我们能看到消息,这里我的报错部分是这样子的:
js
查询语句 SELECT * FROM user WHERE username = ?
其他原因导致的错误! ReferenceError: connectionpool is not defined
原来是我们项目大小写的原因,这里我们改一下,因为之前我们拆分模块的时候,把所有的 connectionpool=> connectionPool
,更改为了小驼峰命名,所以,这里出现问题,建议大家还是细心啊!
再次查询,这里问题已经处理好了!
👍 优化返回信息接口user
之前我们直接返回的data信息,这里我们返回来的部分更改为user用户信息
js
res.send({
code: 200,
data: results[0],
message: '欢迎你的访问!',
});
=> 更改为
res.send({
code: 200,
user: results[0],
message: '欢迎你的访问!',
});
报错
expressJWT is not a function(expressJWT版本语法)
导入和使用expressJWT时遇到问题
c
import expressJWT from 'express-jwt'
app.use(expressJWT({ secret: secretKey }).unless({ path: ['/login'] }))
原因 由于express-jwt 版本的更新,之前的语法不适用于现在的 新版本 ,可以看到现在 是 8 开头的版本 express-jwt8的版本如下图所示:
javascript
app.use(
expressJWT.expressjwt({ secret: secretKey, algorithms: ["HS256"] }).unless({
// path: [/^\/api\//],
path: [
'/',
'/api/login',
'/api/register',
'/api/resetPwd'
]
})
);