JWT的基础使用

剑指Offer17

输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.

思路:将这个矩阵从外层进行遍历,先算出需要遍历几层,然后再根据二维数组的性质,遍历每层的上、右、下、左四层的元素。

public static ArrayList<Integer> solution(int[][] arr){
        if (arr==null){
            return null;
        }
        ArrayList<Integer> list = new ArrayList<>();

        int a=arr.length;//二位数组中有几列(矩阵的行数)
        int b =arr[0].length;//每列中有几个元素(矩阵的列数)
        //打印几圈
       int time = Math.min(a,b)%2==0?Math.min(a,b)/2:Math.min(a,b)/2+1;
       int c1 =0 ;
       int c2 = b-1;
       int r1 = 0;
       int r2 = a-1;
       for (int i =0 ;i<time;i++){
           for (int c = c1  ; c<=c2 ; c++){
               list.add(arr[r1][c]);
           }
           for (int r = r1+1;r<=r2;r++){
               list.add(arr[r][c2]);
           }
           if (r1<r2&&c1<c2){
               for (int c = c2-1;c>c1;c--){
                   list.add(arr[r2][c]);
               }
               for (int r = r2;r>r1;r--){
                   list.add(arr[r][c1]);
               }
           }
           r1++;
           r2--;
           c1++;
           c2--;
       }
       return list;

    }

剑指Offer18

定义栈的数据结构,请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))

思路:定义两个栈,一个为放入元素的栈,另一个辅助栈记录放入元素最小值,当第一个栈需要放入的元素为4、3、7、1,放入第一个元素为4时,辅助栈放入元素4,当栈中放入3时,将辅助栈中的顶层元素与将要放入栈中元素进行比较,如果大于3则将3也同时放入辅助站中,如果小于3,则将辅助栈的顶层元素再次放入辅助栈中,所以栈中最小元素就是辅助栈中的顶层元素。

public class Offer18 {
    Stack<Integer> stack = new Stack<>();
    Stack<Integer> minStack = new Stack<>();
    public void push(int node) {
        if (stack.isEmpty()){
            stack.push(node);
            minStack.push(node);
            return;
        }
        Integer peek = minStack.peek();
        if (node>peek){
            minStack.push(peek);
        }else{
            minStack.push(node);
        }
        stack.push(node);

    }

    public void pop() {
        stack.pop();
        minStack.pop();
    }

    public int top() {
        return stack.peek();
    }

    public int min() {
        return minStack.peek();
    }
}

剑指Offer 19

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

思路:因为栈的弹出只能从栈顶弹出,所以我们要将弹出序列的第一个元素栈顶元素对比,如果相等,就将谈定元素弹出,用弹出序列的第二个元素与栈顶元素比较,如果不相等就继续压栈,直到所有的元素都压入栈顶完毕,左后循环完,如果栈中的元素为空,则返回true

public class Offer21 {

    public static boolean solution1(int[] pushA , int[] popA ){
        if (pushA==null||popA==null||pushA.length==0||popA.length==0){
            return false;
        }
        Stack<Integer> stack = new Stack<>();
        int j = 0;
        for (int i = 0 ;i<pushA.length;i++){
            stack.push(pushA[i]);
            while (j<popA.length&&stack.peek()==popA[j]){
                stack.pop();
                j++;
            }
        }
        return stack.isEmpty()?true:false;

    }
}

JWT

JWT简称jason web token,就是通过jason的格式作为web中的令牌,用域安全的将信息作为jason格式进行传输,再传输的过程还可以进行数据的加密,签名等操作。

传统seesion认证的缺点
1.在传统的信息传递中,我们都是通过session和cookie实现的,但是当服务段发送客服端cookie时,可能会收到拦截,有安全问题,
2.如果用户过多,每个用户都有一个session存储在服务器上,会造成服务器的压力。
3.用户端认证之后,服务端会做记录,如果下次用户请求其他的服务器,就不能得到这个session。
jwt的优点
简洁:可以使用URl、post传递参数,传递的参数小,很轻便,
自包含:jwt中包含了用户所需的信息,避免了多次查询数据库,
jwt是以jason的格式传递参数的,所以在所有的web中都可以传递。

jwt的结构

由三部分组成:header、payload、signature
中间用点进行分隔,进行base64编码。
header:包含两部分令牌的类型(即JWT)和签名的算法。
payload:包含声明,声明是用map结构,在这里可以加入用户的一些信息,但是不建议加入一些私密的信息。
sigature:JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是用 Base64 编码的 header.payload ,再用加密算法加密一下。

jwt的使用

加入依赖

        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
    @Test
    public void test(){
        Calendar instance = Calendar.getInstance();
        //设置jwt有效时间
        instance.add(Calendar.SECOND,300);
        //创建jwt
        String token = JWT.create()
                //加入payload
                .withClaim("username","zhangsan")
                .withExpiresAt(instance.getTime())
                //加入签名并设置使用的算法
                .sign(Algorithm.HMAC256("@#@#EWEWEQ"));
        System.out.println(token);
    }

    @Test
    public void test1(){
        //验证jwt
        JWTVerifier build = JWT.require(Algorithm.HMAC256("@#@#EWEWEQ")).build();
        DecodedJWT verify = build.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1OTcwNjczMjQsInVzZXJuYW1lIjoiemhhbmdzYW4ifQ.vky4fZ5hSzHv6DChQpvFkaLo16Kvh-Qex5kJENDZosk");
        //获取payload中的信息
        System.out.println(verify.getClaim("username").asString());
        //获取过期时间
        System.out.println("过期时间"+verify.getExpiresAt());
    }

JWT在springboot中的使用

@RestController
@Slf4j
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("login")
    public Map<String ,Object > login(User user){
        Map<String, Object> map = new HashMap<>();
        Map<String ,String> token = new HashMap<>();
        log.info("username",user.getUsername());
        try{
            User userDb = userService.login(user);
            token.put("id",userDb.getId());
            token.put("username",userDb.getUsername());
            String token1 = JWTUtil.createToken(token);
            map.put("status",true);
            map.put("sessage","认证成功");
            map.put("token",token1);
        }catch (Exception e){
            map.put("status",false);
            map.put("message",e.getMessage());
            e.printStackTrace();
        }
        return map;
    }

    @RequestMapping("test")
    public Map<String ,Object> test(String token){
        
        Map<String, Object> map = new HashMap<>();
        try{
            JWTUtil.verify(token);
            map.put("status",true);
            map.put("message","认证成功");
        }catch (Exception e){
            map.put("message","认证失败");
            map.put("status",false);
        }
        return map;
    }
}

前端存放token

token可以存放在LocalStorage和SessionStorage中

LocalStorage除非主动删除,否则会永久存储在浏览器中。

SessionStorage只在当前所在窗口关闭前有效,窗口关闭后其存储数据也就会被自动清除。

.then(res =>{
                    if(res.data['code']==200){
                        localStorage.clear()
                        localStorage.setItem('info',1)
                        localStorage['flag']=1
                        // localStorage.setItem('flag',1)
                        sessionStorage.clear()
                        // sessionStorage['userid']=JSON.stringify(res.data.userInfo.id)
                        sessionStorage.setItem('userid',JSON.stringify(res.data.userInfo.id))
                        sessionStorage['token']=JSON.stringify(res.data.token)
                        this.$message({
                            message:'登录成功',
                            type:'success'
                        })
                        this.$router.push('/home')
                    }else{
                        this.$message({
                            message:'用户名或者密码错误',
                            type:'warning'
                        })
                        }
                })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值