1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > ASP .NET + Angular前后端分离实现简单投票系统(JWT登录用户认证)

ASP .NET + Angular前后端分离实现简单投票系统(JWT登录用户认证)

时间:2023-01-12 04:36:18

相关推荐

ASP .NET + Angular前后端分离实现简单投票系统(JWT登录用户认证)

之前讲了投票模块的功能api,要实现用户登录后才可以进行投票,对登录用户进行认证,我采用的是JWT(json web token),在请求头加入Authorization,并加上Bearer标注。

大概流程如下:

1 用户请求登录服务器

2 服务器接到请求生成一个token,返回给浏览器

3 之后浏览器的每一次请求都带着这个token

4 服务器收到后验证是否正确,是否被更改过,认证通过就可以返回对应的response

首先编写一个创建Token的工具类

JwtUtil.cs

using Microsoft.Extensions.Configuration;using Microsoft.IdentityModel.Tokens;using System;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Text;using Vote_Api.Models;namespace Vote_Api.Utility{public class JwtUtil{private IConfiguration _configuration {get; }public JwtUtil(IConfiguration configuration){_configuration = configuration;}public string getToken(){var claims = new[]{new Claim(JwtRegisteredClaimNames.NameId, "zxx"),new Claim(ClaimTypes.Role, "admin")};var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"])); // 获取密钥var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); //凭证 ,根据密钥生成var token = new JwtSecurityToken(issuer: "Lola", //签发者audience: "Voter", //接受者claims: claims,expires: DateTime.Now.AddMinutes(10), //设置过期时间为10分钟signingCredentials: creds);return new JwtSecurityTokenHandler().WriteToken(token);}}}

其次还要在Startup.cs的ConfigureServices中添加配置

public void ConfigureServices(IServiceCollection services){services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuer = true,//是否验证IssuerValidateAudience = true,//是否验证AudienceValidateLifetime = true,//是否验证失效时间ValidateIssuerSigningKey = true,//是否验证SecurityKeyValidIssuer = "Lola",ValidAudience = "Voter",IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["SecurityKey"])),RequireExpirationTime = true};options.Events = new JwtBearerEvents(){//验证失败OnAuthenticationFailed = context =>{context.NoResult();context.Response.StatusCode = 401;context.Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = context.Exception.Message;Debug.WriteLine("OnAuthenticationFailed: " + context.Exception.Message);return pletedTask;},};});}

在Startup.cs的Congiure方法中添加一行

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.UseAuthentication();}

编写登录模块的业务逻辑

ILoginService.cs

using Vote_Api.Models;namespace Vote_Api.Service.IService{public interface ILoginService{string CheckLogin(string username, string pwd);bool UpdatePwd(string oldPwd, string newPwd);}}

实现类LoginService.cs

using System;using Vote_Api.Models;using Vote_Api.Service.IService;using Vote_Api.Utility;namespace Vote_Api.Service.ServiceImpl{public class LoginService : ILoginService{private readonly VoteContext _context;private readonly JwtTokenUtil _tokenUtil;public LoginService(VoteContext context, JwtTokenUtil tokenUtil){_context = context;_tokenUtil = tokenUtil;}public string CheckLogin(string userId, string pwd){string result = "";try{User user = _context.User_Info.Find(userId); //查找用户id,返回用户(一直觉得这个方法不好,但能力有限,将就看吧)if (user.Passwd == pwd) //判断密码是否正确{result = "{\"token\":\"";result += _tokenUtil.getToken(); //用户密码正确,发放一个tokenresult += "\"}";}else{result = "error";}}catch (Exception ex){Console.WriteLine(ex);}return result;}public bool UpdatePwd(string oldPwd, string newPwd){throw new NotImplementedException();}}}

编写LoginController

using Microsoft.AspNetCore.Authorization;using Microsoft.AspNetCore.Mvc;using Vote_Api.Service.IService;namespace Vote_Api.Controllers{[Route("api/login")][ApiController]public class LoginController : Controller{private readonly ILoginService _service;public LoginController(ILoginService service){_service = service;}[HttpGet("CheckLogin")]public string CheckAccount(string username, string pwd){var token = _service.CheckLogin(username, pwd);if(token != "error"){Response.Cookies.Append("token",token);}return _service.CheckLogin(username, pwd);}[HttpPost("UpdatePwd")][Authorize] //增加权限验证,访问该api的请求头必须带着发放的tokenpublic bool UpdatePwd(string oldPwd, string newPwd){return _service.UpdatePwd(oldPwd, newPwd);}}}

同样在之前的VoteController中的需要验证的api方法前添加[Anthorize]

用postman测试

发现登陆成功后,得到一个token,之后我们请求头都带上这个token,在Authorization中添加 Bearer Token,将刚刚的token复制过去即可

成功得到数据

如果请求头不加token,就没有结果

另外之后前端访问api还会涉及到一个跨域请求的问题,这里先写好

直接在Startup.cs的ConfigfureService方法中添加Cors

public void ConfigureServices(IServiceCollection services){services.AddCors(options => options.AddPolicy("CorsPolicy",builder =>{builder.AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowAnyHeader().AllowCredentials();}));}

在Configure方法中添加,需注意位置,必须在app.UseMvc()前面

public void Configure(IApplicationBuilder app, IWebHostEnvironment env){app.UseCors("CorsPolicy");}}

这样就可以跨域访问啦

到此,登录模块的api已经完成,写得不是很好,仅供参考

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。