认证模块

单点登录

image-20210903083545422

image-20210903084459227

image-20210903084833505

image-20210903093404311

身份验证的几代更进

怎样判断用户的登录验证

第一代解决方案

几个服务用户都在访问,怎样确认用户信息的问题,是同一个用户就可以让他共享这几个服务,不是就不共享

将每个用户的jseessionid 放到redsi池中,每次访问不同的模块都能拿到同样的数据 确认为同一个人在操作

用到了seesion redis, 乔布斯那个年代这样做

第二代

我们用到了将jseesion id放到seesion中,又将seesion放到redis中,这样相当于把jsseesion id放到一个盒子中,然后又将这个盒子放到另一个盒子中,这样浪费性能

所以这时候人们直接用token, 将用户认证成功的信息放到token中,浏览器中放一份, redis放一份 请求过来服务器中只需要比对 token和redis中是否一样,如果一样就可以在任何模块中登录

用户每次登录都要连接一次数据库对token进行判断 ,也过时了

image-20210903175635804

第三代

像京东类的电商 平台,他会直接将jwt生成的token(用户输入正确的用户名和密码)返回写在浏览器中,然后将用户信息存储在这个token中,token存在cookie中,用户访问会直接访问到认证中心,认证中心会拿着这个token去解,如果 解成功了就代表这次请求是合法的,不会像第二代那样再去访问redis那样看了 这样直接将由数据的访问直接变成了jar包的解密

image-20210903195824948

image-20210903200908097

image-20210903201717287

image-20210903201558027

image-20210903202036072

主动登录 (自己点的)

image-20210904155101642

主动登录的过程可以理解 为: 自己点击登录后访问的是认证中心的登录 页面,携带一个retrun url的地址(returnurl还是自己目前的这个起始页,因为请求登录一系列处理还是走原来的访问的业务),到了认证的index页面后,image-20210904155812733

会调用这个login方法,将用户名和密码传到后台,后台返回token,

如果 token有值

就将页面置为之前 的起始页面,(即登录页面)

被动登录 (登录业务方法)

做个举证:

老token为不为空:代表之前 有没有主动登录

新token为不为空,代表浏览器现在访问的这个方法当前是否需要登录

image-20210904163238945

image-20210904163943169

浏览器中的token就是returnUrl的token

解决的问题

在认证中心解token的时候image-20210908113108722

加密盐值是用客户端请求的ip的, 解密的时候由于客户端的请求被 拦截器拦下来了然后在拦截器中调用认证中心的verify方法,然后我用这个verify的requestIp地址 Ip去解,是解不开的,解出来 的decode 编码是 faild然后这 导致每次登录 验证都是错误的,

image-20210909115331051

image-20210909115448472

解决:

image-20210909120455659

image-20210909120521450

由于我没有nignx登录 所以我的盐值 ,我直接设置成为固定的字符串

社交登录

image-20210909151053277

授权码代表着用户已经授权给第三方服务器,理论上我的谷粒商城可以使用第三方服务器的用户信息了

但是有个Oauth2,

授权码交给我们的服务器后,我们的服务器还得再去用这个授权码与第三方服务器去交换access_token, 用 这个token令pai去交换用户信息

(一旦授权码不一样了,assess_tokeni当然也不一样了,本来是用授权码去交换的,交换出来了当然是你这个授权码与这匹配的token,如果此时授权码不一样了,那assess_token当然不能用了 )

image-20210909151815555

总结下来就是四个地址

四个地址

第一个地址:访问第三方服务器授权地址 返回一个第三方的登录 页面

image-20210910111838488

第二个地址:生成授权码地址

第三个地址:授权码换取access_token地址

第四个地址:用access_token去交换用户信息地址

四个地址这间的依次使用

package com.atguigu.gamll.passport.controller;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.util.HttpclientUtil;

import java.util.HashMap;
import java.util.Map;

public class TestOauth2 {

    public static String getCode(){

        // 1 获得授权码
        // 187638711
        // http://passport.gmall.com:8085/vlogin

        String s1 = HttpclientUtil.doGet("https://api.weibo.com/oauth2/authorize?client_id=187638711&response_type=code&redirect_uri=http://passport.gmall.com:8085/vlogin");

        System.out.println(s1);

        // 在第一步和第二部返回回调地址之间,有一个用户操作授权的过程

        // 2 返回授权码到回调地址

        return null;
    }

    public static String getAccess_token(){
        // 3 换取access_token
        // client_secret=a79777bba04ac70d973ee002d27ed58c
        String s3 = "https://api.weibo.com/oauth2/access_token?";//?client_id=187638711&client_secret=a79777bba04ac70d973ee002d27ed58c&grant_type=authorization_code&redirect_uri=http://passport.gmall.com:8085/vlogin&code=CODE";
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("client_id","187638711");
        paramMap.put("client_secret","a79777bba04ac70d973ee002d27ed58c");
        paramMap.put("grant_type","authorization_code");
        paramMap.put("redirect_uri","http://passport.gmall.com:8085/vlogin");
        paramMap.put("code","b882d988548ed2b9174af641d20f0dc1");// 授权有效期内可以使用,没新生成一次授权码,说明用户对第三方数据进行重启授权,之前的access_token和授权码全部过期
        String access_token_json = HttpclientUtil.doPost(s3, paramMap);

       Map<String,String> access_map = JSON.parseObject(access_token_json,Map.class);

       System.out.println(access_map.get("access_token"));
       System.out.println(access_map.get("uid"));

        return access_map.get("access_token");
    }

    public static Map<String,String> getUser_info(){

        // 4 用access_token查询用户信息
        String s4 = "https://api.weibo.com/2/users/show.json?access_token=2.00HMAs7H0p5_hMdbefcb34140Lydjf&uid=6809985023";
        String user_json = HttpclientUtil.doGet(s4);
        Map<String,String> user_map = JSON.parseObject(user_json,Map.class);

        System.out.println(user_map.get("1"));

        return user_map;
    }


    public static void main(String[] args) {

        getUser_info();

    }
}

image-20210909155956135

image-20210909205855657

三码去交换assess_token的理解

(app secret只有我们app有,其服务器没有,生成的授权码只能由我们自己去交换assess token,其他的交换不了)

为什么我要创建出这个应用还有这两个码 app key 和app secret ,

因为我们的应用拿到授权码之前 都是通过服务器进行交互的,这个授权码是暴露的,不法分子可以拦截这个授权码,然后去第三方交换你服务器上的数据 ,需要避免这种情况发生, 我们得拿着授权码和app key, app sercet,去到第三方服务器交换asses_token, 就算被别人拦截了授权码,他没有另外两个码,是不可能交换出数据的,得不到asses_token就使用不了我的数据 ,所以就安全,

因为Oauth要求asses_token是要另外这两个才能得到的

(所以我们提前给第三方平台打了招呼说,说为了防止黑客侵入,我们提前要设置一个两个码,只有你请求过来授权码和app key, app secret 这三个东西才能交换数据, 黑客只拿到授权码是得不到第三方服务器的数据 的 )

授权码 app key app secret 这三个去交换asses_token

image-20210909210406694

其中的授权码变了,可以理解为变更了用户, 用户变了,那拿去换取的asses_token一定变了

image-20210909165153742

开放平台回调的理解

开放平台 一旦授权成功后,要将授权码给送到被 授权方,需要回调下,这个地址就是回调地址,也就是gmall商城中的地址,填写的时候商城中的方法地址要和开放平台的回调地址要保持一致

image-20210909212619049

社交登录和项目的整合

image-20210910113440937

posted @ 2021-09-29 22:29  JargonFire  阅读(171)  评论(0)    收藏  举报