本篇文章我们来介绍C++高性能服务器的开发
1.用户认证和鉴权
JWT认证
1.前后端token的认证流程:
前端发送登陆请求 -- > 后端登陆接口接受 -->后端数据处理后返给前端token --> 前端将token存储后 -->每次请求都带着这问 --->后端设置jwto截器 -->只放ken拦行登陆接口 -->如果前端访问别的接口必须带有token --> 否则被拦个token去访截器拦截 并让前端回复到登陆页面
2、Token的处理方式:
JWT的token当服务端返回以后,是需要客户端进行主动地动作的,并不是像cookie一样,在后边的请求,都会自动带过去。这样就导致了如下几种做法:
**将Jwt的token作为cookie返回给客户端。**这样后续的请求都会带着这个token过来。这样在拦截的时候,就可以使用了。
**将Jwt的token作为返回字符串,先返回给前端,前端再后续请求时,写到anthorization的request的head中,**这个做法需要 编程去做,而且通用的做法,都是在ajax当中去做。构造请求。
**将Jwt的token作为返回字符串,先返回给前端,前端再后续请求时,将Jwt的token写到token的request的head中,**这个做法,也是编程实现,只不过具体做法,也是通过ajax进行。构造请求。只不过是自定义的head。
其实jwt的token也可以作为URL的参数进行传递的,这也是一个方法。
另外,jwt返回给前端的token,一般的做法都是放到localStorage当中,也就是前端浏览器的存储空间当中。可以将token存储在 localstorage里面,需要防止xss攻击
3、例子:
在登陆请求成功后把后端返回数据存储到浏览器
定义request.js 统一处理发送的请求为其加上token ,统一处理响应 若包含统一返回类code为 token未验证成功code 401 则让用户到登陆页面重新登陆
注意:客户端必须主动操作jwt返回的token,这个就不是自动的过程了。
JWT的方案 1、用户去认证中心登录,认证中心生成JWT,返回给客户端。
2、客户端带着jwt,请求其他的多个系统。
3、其他的系统,自己解析jwt,如果能解析,就说明登录成功,就可以继续业务。
通常,这个方案会将用户名等信息放到jwt当中,这样就不用认证中心校验了。
看一下代码示例:
cpp
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <openssl/hmac.h>
std::string base64_encode(const std::string& input) {
const std::string charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::stringstream result;
size_t i = 0;
while (i < input.length()) {
uint32_t octet_a = i < input.length() ? static_cast<uint8_t>(input[i++]) : 0;
uint32_t octet_b = i < input.length() ? static_cast<uint8_t>(input[i++]) : 0;
uint32_t octet_c = i < input.length() ? static_cast<uint8_t>(input[i++]) : 0;
uint32_t triple = (octet_a << 16) + (octet_b << 8) + octet_c;
result << charset[(triple >> 18) & 63]
<< charset[(triple >> 12) & 63]
<< charset[(triple >> 6) & 63]
<< charset[triple & 63];
}
size_t padding_length = input.length() % 3 == 1 ? 2 : (input.length() % 3 == 2 ? 1 : 0);
for (size_t i = 0; i < padding_length; ++i)
result.seekp(-1, std::ios_base::end) << '=';
return result.str();
}
std::string jwt_encode(const std::string& header, const std::string& payload, const std::string& secret_key) {
std::stringstream encoded_token;
// Encode header
std::string encoded_header = base64_encode(header);
encoded_token << encoded_header << '.';
// Encode payload
std::string encoded_payload = base64_encode(payload);
encoded_token << encoded_payload;
// Sign token with secret key using HMAC-SHA256 algorithm
unsigned char hmac_result[EVP_MAX_MD_SIZE];
unsigned int hmac_length;
HMAC(EVP_sha256(), secret_key.c_str(), secret_key.length(), reinterpret_cast<const unsigned char*>(encoded_token.str().c_str()), encoded_token.str().length(), hmac_result, &hmac_length);
// Append signature to the token
std::string signature(hmac_result, hmac_result + (hmac_length > 32 ? 32 : hmac_length));
return encoded_token.str() + '.' + base64_encode(signature);
}
int main() {
std::string header = R"({"alg":"HS256","typ":"JWT"})";
std::string payload = R"({"sub":"1234567890","name":"John Doe","iat":1516239022})";
std::string secret_key = "your_secret_key_here";
std::string jwt_token = jwt_encode(header, payload, secret_key);
std::cout << "Generated JWT: " << jwt_token << std::endl;
return 0;
}
在实际开发中 需要使用适当的JWT库来处理JWT生成和验证的复杂性。
好了 本篇文章就到这里 在这里我想向大家推荐一个课程: