详解JWT身份验证:在.NET Core后台与Vue.js前端的实现
发表时间: 2024-01-04 12:09
概述:JSON Web Token(JWT)是一种用于安全传输信息的标准。主要用于身份验证和信息传递,通过头部、载荷和签名构成。在.NET Core中,可通过
Microsoft.AspNetCore.Authentication.JwtBearer实现后台服务,提供生成、刷新和验证Token的接口。前端使用Vue.js结合axios发送请求,通过拦截器实现自动刷新Token,确保安全可靠的身份验证和信息传递。
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间传输信息的轻量级、自包含的标准。JWT由三部分组成:头部(Header)、载荷(Payload)、签名(Signature)。它通常被用于身份验证和信息传递。
{ "alg": "HS256", "typ": "JWT" }
{ "sub": "1234567890", "name": "John Doe", "iat": 1516239022 }
JWT主要用于在网络应用中安全地传递声明。常见用途包括身份认证和信息交换。生成的JWT可以被验证,信任,并且不易被篡改。
JWT的原理基于对称或非对称加密。生成JWT时,使用密钥对头部和载荷进行签名。验证时,接收到的JWT通过相同的过程重新计算签名,并与接收到的签名进行比较。由于签名使用密钥生成,只有拥有密钥的一方才能生成有效的签名。
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
services.AddAuthentication(options =>{ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;}).AddJwtBearer(options =>{ options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your_secret_key")) };});
app.UseAuthentication();
[ApiController][Route("api/auth")]public class AuthController : ControllerBase{ private readonly JwtService _jwtService; public AuthController(JwtService jwtService) { _jwtService = jwtService; } [HttpPost("login")] public IActionResult Login([FromBody] LoginRequest request) { // 验证用户名和密码,生成 ClaimsIdentity ClaimsIdentity identity = ... // 生成 JWT string token = _jwtService.GenerateToken(identity); return Ok(new { Token = token }); }}
[Authorize][HttpPost("refresh")]public IActionResult RefreshToken(){ // 从当前用户的 Claims 中获取信息,生成新的 Token ClaimsIdentity identity = ... string newToken = _jwtService.GenerateToken(identity); return Ok(new { Token = newToken });}
[Authorize][HttpGet("protected")]public IActionResult ProtectedResource(){ // 受保护的资源 return Ok(new { Message = "This is a protected resource." });}
npm install axios
import axios from 'axios';// 每次请求前检查 Token 是否过期,如果过期则刷新axios.interceptors.request.use(async (config) => { const token = localStorage.getItem('jwtToken'); if (token) { // 检查 Token 是否过期 const decodedToken = parseJwt(token); const currentTimestamp = Math.floor(Date.now() / 1000); if (decodedToken.exp < currentTimestamp) { // Token 过期,刷新 Token await refreshToken(); } config.headers.Authorization = `Bearer ${token}`; } return config;});// 刷新 Tokenasync function refreshToken() { const token = localStorage.getItem('jwtToken'); const response = await axios.post('api/auth/refresh', null, { headers: { Authorization: `Bearer ${token}` } }); const newToken = response.data.Token; localStorage.setItem('jwtToken', newToken);}// 发送包含 JWT 的请求async function sendRequest() { try { const response = await axios.get('api/auth/protected'); console.log(response.data); } catch (error) { console.error('Request failed:', error); }}// 解析 JWTfunction parseJwt(token) { const base64Url = token.split('.')[1]; const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) { return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); }).join('')); return JSON.parse(jsonPayload);}
以上是一个简单的示例,实际应用中需要考虑更多的安全性和错误处理。确保在生产环境中使用 HTTPS 以保障数据传输的安全性。