Cors跨域和Jwt(Token)

目录

一,浏览器的同源策略

1,同源与跨域

2,浏览器的同源策略

二,跨域处理方案(后端)

三,Cors过滤器

实现方法:①:实现Filter接口②:重写init,dofilter,destroy。③:dofilter中设置跨域配置

四,Jwt(Token)

Token的使用:Maven项目

1,导入依赖(版本自己选择)

2,编写工具类

3,用户登录的时候创建Token,放在响应头中。(使用原生的servletResponse)

4,写一个过滤器判断请求中是否存在token存在则对Token进行校验。成功则放行,不成功则返回失败。


一,浏览器的同源策略

1,同源与跨域

        url:  通讯协议://IP地址:端口号/资源路径
        两次请求的协议,ip,端口号都相同,我们认为两次请求的同源的
        否则,不同源,需要跨域(Cors)。

2,浏览器的同源策略

        浏览器发送请求,同源可以发送,不同源不能发送请求。(浏览器的安全机制)
        部分html标签支持跨域script,,a,link,img等

        但在项目中使用Ajax调用接口,默认是不能跨域的。
报错图片:

二,跨域处理方案(后端)

1,使用nginx服务器

2,Cors跨域资源共享,后端设置可以跨域。

三,Cors过滤器

跨域请求时复杂请求。
复杂请求跨域访问,会先发一次预检请求,请求方式时OPTIONS。
如果预检请求允许,发送真正的请求,不允许则控制台报错。

实现方法:
①:实现Filter接口
②:重写init,dofilter,destroy。
③:dofilter中设置跨域配置
 
HttpServletResponse  resp=(HttpServletResponse)servletResponse;
        HttpServletRequest  req=(HttpServletRequest)servletRequest;

        //设置cors:允许跨域访问

//        预检请求方式是:OPTIONS

//        1\允许哪些域可以访问我
        resp.setHeader("Access-Control-Allow-Origin","*");
//        resp.setHeader("Access-Control-Allow-Origin","http://localhost:8080");
//        resp.setHeader("Access-Control-Allow-Origin",req.getHeader("Origin"));

//        2、允许哪些请求方式
        resp.setHeader("Access-Control-Allow-Methods","get,post,OPTIONS");

//        3、请求头中包含
        resp.setHeader("Access-Control-Allow-Headers","token");

//        4、跨域是否允许携带cookie
        resp.setHeader("Access-Control-Allow-Credentials","true");

//        5、预检请求的时间间隔
        resp.setHeader("Access-Control-Max-Age","3600");

//        6、 可以向客户端浏览器暴露哪些请求头
        resp.setHeader("Access-Control-Expose-Headers", "token");

//        将请求交给目标资源
        filterChain.doFilter(req, resp);

跨域不能携带cookie和session会话跟踪。所以使用token。

四,Jwt(Token)

网址:https://jwt.io/

介绍:JWT就是一个带有用户信息的加密字符串。JWT可以使用密钥(使用HMAC算法)或使用RSA或ECDSA的公钥/私钥对进行签名。通常用于用户登录。

Jwt组成:Header(头部),Payload(载荷),Signature(签名)三部分组成,中间以点分隔。

 类库:进入官方-----libraries----Filterby(选择Java)-----自己选择下载

Token的使用:Maven项目
1,导入依赖(版本自己选择)
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.11.0</version>
</dependency>

2,编写工具类
/**
 * 用于生成和解析JWT
 */
public class JWTUtils {

    /**
     * 声明一个秘钥
     */
    private static final String SECRET = "leige";


    /**
     * 生成JWT
     *
     * @param userId   用户编号
     * @param username 用户名
     * @param auth     用户权限
     */
    public String createToken(Integer userId, String username, List<String> auth) {
        //得到当前的系统时间
        Date currentDate = new Date();
        //根据当前时间计算出过期时间 定死为5分钟
        Date expTime = new Date(currentDate.getTime() + (1000 * 60 * 5));
        //组装头数据
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");
        return JWT.create()
                .withHeader(header) //头
                .withClaim("userId", userId) //自定义数据
                .withClaim("username", username) //自定义数据
                .withClaim("auth", auth) //自定义数据
                .withIssuedAt(currentDate) //创建时间
                .withExpiresAt(expTime)//过期时间
                .sign(Algorithm.HMAC256(SECRET));
    }

    /**
     * 验证JWT并解析
     *
     * @param token 要验证的jwt的字符串
     */
    public static Boolean verifyToken(String token) {
        try{
            // 使用秘钥创建一个解析对象
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            //验证JWT
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            return true;
        }catch (TokenExpiredException e){
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 获取JWT里面相前的用户编号
     */
    public Integer getUserId(String token){
        try{
            // 使用秘钥创建一个解析对象
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            //验证JWT
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            Claim userId = decodedJWT.getClaim("userId");
            return userId.asInt();
        }catch (TokenExpiredException e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取JWT里面相前的用户名
     */
    public static String getUsername(String token){
        try{
            // 使用秘钥创建一个解析对象
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            //验证JWT
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            Claim username = decodedJWT.getClaim("username");
            return username.asString();
        }catch (TokenExpiredException e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取JWT里面相前权限
     */
    public List<String> getAuth(String token){
        try{
            // 使用秘钥创建一个解析对象
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();
            //验证JWT
            DecodedJWT decodedJWT = jwtVerifier.verify(token);
            Claim auth = decodedJWT.getClaim("auth");
            return auth.asList(String.class);
        }catch (TokenExpiredException e){
            e.printStackTrace();
        }
        return null;
    }

}
3,用户登录的时候创建Token,放在响应头中。(使用原生的servletResponse)
@RequestMapping("/login")
    public R loginUsers(String uname, String upassword, HttpServletResponse resp) throws UnsupportedEncodingException {
        Users user = service.Userlogin(uname);
        if (!user.getUname().equals(uname)){
            return R.loginfail();
        }else if(!user.getUpassword().equals(upassword)){
            return R.fali("用户密码错误,请重新输入");
        }else {
            String token = TokenUtil.toToken();
            //响应token
            resp.setHeader("token",token);
            return R.sussce("登录成功");
        }
    }

4,写一个过滤器判断请求中是否存在token
存在则对Token进行校验。成功则放行,不成功则返回失败。
//        获取请求头中的token
        String token = req.getHeader("token");
//        token为空或校验失败
        if (token==null || !TokenUtil.validateJWT(token)){
//            没有登录
            PrintWriter out = resp.getWriter();
            ObjectMapper mapper = new ObjectMapper();

            out.write(mapper.writeValueAsString(R.loginfail()));
            out.close();
        }else {
//            放行
            filterChain.doFilter(req,resp);
        }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.net中使用JWT(JSON Web Token)实现跨域认证是一种常见的做法。跨域是指前端应用程序在一个域上发送请求,但请求的目标资源位于另一个域上,由于浏览器的同源策略,默认情况下是不允许跨域请求的。 在ASP.NET中,可以通过配置CORS策略以允许跨域请求。首先,在Web.config或应用程序的Startup.cs文件中添加CORS中间件,并允许特定的来源域或Http请求方法: ```csharp // Startup.cs public void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowCorsPolicy", builder => builder .AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader()); }); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseCors("AllowCorsPolicy"); //其他中间件配置 } ``` 然后,在控制器或API端点中,通过`Authorize`属性进行JWT认证: ```csharp // Controller.cs [Authorize] [ApiController] [Route("api/[controller]")] public class MyController : ControllerBase { // ... } ``` 这将确保只有带有有效JWT的请求才能访问该控制器的API。 此外,在生成JWT时,需要将适当的CORS头信息包含在令牌中: ```csharp // JwtGenerator.cs public string GenerateJwtToken() { var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes("your_secret_key"); var tokenDescriptor = new SecurityTokenDescriptor { // 设置其他Jwt相关参数 Subject = new ClaimsIdentity(new Claim[] { new Claim(ClaimTypes.Name, "your_name") }), // 设置CORS Header = new JwtHeader(new SigningCredentials( new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256)) { {"Access-Control-Allow-Origin", "your_origin_domain"} } }; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } ``` 通过在生成JWT时设置`Access-Control-Allow-Origin`头,将允许指定的域进行跨域请求。 总结而言,使用.net中的JWTCORS,可以实现安全的跨域认证。配置CORS策略以允许特定的跨域请求,并在生成JWT时设置适当的CORS头信息,以确保只有带有有效JWT的请求才能访问受保护的API。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值