JWT实现跨域登录校验

JWT实现跨域登录校验

需求

需求背景:项目前后端分离,前端页面在一个服务器上,后台接口在另一个服务器,也就是非同源跨域请求。页面通过调用接口获取数据并对数据库进行crud的操作,并需要在用户登录的条件下进行操作,这里我们利用JWT(Json Web Token)解决跨域获取登录用户信息的问题。

思路

1.首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTPPOST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
2.后端核对用户名和密码成功后,将用户的id等其他信息作为JWT
Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT。形成的JWT就是一个形同lll.zzz.xxx的字符串。
3.后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
4.前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)
5.后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。
6.验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

用法

1.前端服务器页面点击登录填写登录信息
在这里插入图片描述
在这里插入图片描述
这里页面登录通过ajax jsonp 实现跨域请求后台服务器登录接口,下面代码后台登录代码,登录成功生成token。

	@RequestMapping(value = "login",produces = "text/script;charset=UTF-8")
	@ResponseBody
	public String login(HttpServletRequest request, HttpServletResponse response,String callback,String userName,String passWord) {
		Map<String,Object> map =MapUtils.newHashMap();
		if(StringUtils.isNotBlank(userName)&&StringUtils.isNotBlank(passWord)){
			User user = UserUtils.getByLoginCode(userName);
			if(user!=null&&StringUtils.isNotBlank(user.getUserCode())){
				if(user.getPassword().equals(passWord)){
					//生成jwt token
					String token = JwtUtils.geneJsonWebToken(user);
					map.put("result","true");
					map.put("message","登录成功!");
					map.put("token",token);
					org.json.JSONObject object = new org.json.JSONObject(map);
					return callback + "(" + object.toString() + ")";
				}else{
					map.put("result","false");
					map.put("message","登录失败,密码有误!");
					org.json.JSONObject object = new org.json.JSONObject(map);
					return callback + "(" + object.toString() + ")";
				}
			}else{
				map.put("result","false");
				map.put("message","登录失败,用户不存在!");
				org.json.JSONObject object = new org.json.JSONObject(map);
				return callback + "(" + object.toString() + ")";
			}
		}else{
			map.put("result","false");
			map.put("message","登陆失败,用户名或密码不能为空!");
			org.json.JSONObject object = new org.json.JSONObject(map);
			return callback + "(" + object.toString() + ")";
		}
	}

下面是JwtUtils代码

package com.jeesite.common.jwt;

import com.jeesite.modules.sys.entity.User;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;

/**
 * jwt工具类
 */
public class JwtUtils {


    public static final String SUBJECT = "xdclass";

    //public static final long EXPIRE = 1000*60*60*24*7;  //过期时间,毫秒,一周
    public static final long EXPIRE = 1000*60*10;  //过期时间,毫秒,一周
    //秘钥
    public static final  String APPSECRET = "xd666";

    /**
     * 生成jwt
     * @param user
     * @return
     */
    public static String geneJsonWebToken(User user){

        if(user == null || user.getId() == null || user.getUserCode() == null
                || user.getPassword()==null){
            return null;
        }
        String token = Jwts.builder().setSubject(SUBJECT)
                .claim("id",user.getId())
                .claim("userName",user.getUserCode())
                .claim("passWord",user.getPassword())
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis()+EXPIRE))
                .signWith(SignatureAlgorithm.HS256,APPSECRET).compact();

        return token;
    }


    /**
     * 校验token
     * @param token
     * @return
     */
    public static Claims checkJWT(String token ){

        try{
            final Claims claims =  Jwts.parser().setSigningKey(APPSECRET).
                    parseClaimsJws(token).getBody();
            return  claims;

        }catch (Exception e){
            e.printStackTrace();
        }
        return null;

    }



}

登录校验成功后,把token存在map中连着登录信息一起返回给前台页面,页面获取到token后使用locationstorage把token存到浏览器中(locationstorage可当做大型号的cookie使用,想了解可以自己搜一下)

<script>
    function submit() {
        var userName = $("#userName").val();
        var passWord = $("#passWord").val();
        $.ajax({
            type:"post",
            url:"http://192.168.11.5:8081/js/a/pm/pmAuctionProcess/login",
            data:{'userName': userName,'passWord':passWord},
            dataType:"jsonp",
            crossDomain:true,
            jsonpCallback:"jsonpCallbackFun",
            jsonp:"callback",
            success:function(data){
				if(data!=null&&data['result']=="true"){
					$.MsgBox.Alert("消息", data['message']);
					console.log(data);
				if(!window.localStorage){
            alert("浏览器支持localstorage");
        }else{
            var storage=window.localStorage;
            //写入a字段
            storage["token"]=data['token'];
            console.log(storage.token);
        }
				}
                

            },
            error: function() {
            }
        });
    }
</script>

这时已经存到浏览器的locationstorage中了
在这里插入图片描述
然后页面通过jsonp请求获取后台数据时,在data参数中加上这个token传到后台进行校验

    @RequestMapping(value = "getData",produces = "text/script;charset=UTF-8")
    @ResponseBody
    public String getData(String goodsCode,String token, HttpServletRequest request, HttpServletResponse response,String callback) {
        //解析token获取用户信息
        User user = getUserByToken(token);
        .........
        }

/**
     * 解析token获取用户
     * @param token
     * @return
     */
    public User getUserByToken(String token){
        Claims claims= JwtUtils.checkJWT(token);
        System.out.println(claims);
        User user = new User();
        if(claims!=null){
            user = UserUtils.get(claims.get("id").toString());
        }
        return user;
    }

每次访问后台接口都要先通过传来的token进行身份校验再进行访问。退出登录后,页面将locationstorage 清理掉即可!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值