• Oauth2.0认证原理


    Oauth2.0 认证协议

    Oauth2.0 应用场景: 微信联合登录     授权管理  

    互联网开放平台互相调用保证安全

        微信提供api  给toov5调用  然后就可以获取一些微信的信息  比如微信头像

        开放平台有 支付宝  微信 百度等等

        不同的开放平台 对接的oauth2.0协议流程都是相同,无非接口地址不同

      

    Oauth2.0原理 (appId appsecret access_token  openId  回调地址 授权地址)

    使用:

       在微信开放平台申请对应的appId信息

        toov5生成登录授权连接

        用于在确认微信登录之后  跳转回到回调地址(配置域名权限)

        获取到授权码 使用授权码获取对应的accessToken(调用腾讯借口权限)

        使用accessToken+openId获取用户相关信息 (openid 开放userId)

      

    配置 授权访问连接: 通过controller跳转到 腾讯的连接

    用户点击确定登录时候  进入到callback,并且获取到前面返回的code

    拿到code 后面就可以获取到相应的 token 和 id了

     第一步:用户同意授权,获取code
    2 第二步:通过code换取网页授权access_token
    3 第三步:刷新access_token(如果需要)
    4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
    5 附:检验授权凭证(access_token)是否有效

    maven:

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.0.0.RELEASE</version>
        </parent>
        <dependencies>
    
    
    
            <!-- SpringBoot 对lombok 支持 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <!-- SpringBoot web 核心组件 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </dependency>
            <!-- SpringBoot 外部tomcat支持 -->
            <dependency>
                <groupId>org.apache.tomcat.embed</groupId>
                <artifactId>tomcat-embed-jasper</artifactId>
            </dependency>
    
            <!-- springboot-log4j -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-log4j</artifactId>
                <version>1.3.8.RELEASE</version>
            </dependency>
            <!-- springboot-aop 技术 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
            <!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
            <dependency>
                <groupId>commons-lang</groupId>
                <artifactId>commons-lang</artifactId>
                <version>2.6</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>
    
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
            </dependency>
            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>
        </dependencies>

    yml:

    spring:
      mvc:
        view:
          # 页面默认前缀目录
          prefix: /WEB-INF/jsp/
          # 响应页面默认后缀
          suffix: .jsp
          
    appid: wx5c43fde3c9733d9e
    secret: b8b217126c33a5fb7074927d5e72a81a
    redirectUri: http://127.0.0.1:8080/callback
    ### 生成微信授权   官方提供的授权接口
    authorizedUrl: https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
    ###获取code后,请求以下链接获取access_token
    access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    ###拉取用户信息(需scope为 snsapi_userinfo)
    userinfo: https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

    Controller:

    import javax.servlet.http.HttpServletRequest;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.alibaba.fastjson.JSONObject;
    import com.itmayiedu.base.BaseApiService;
    import com.itmayiedu.utils.HttpClientUtils;
    import com.itmayiedu.utils.WeiXinUtils;
    
    @Controller
    public class OauthController extends BaseApiService {
    
        @Autowired
        private WeiXinUtils weiXinUtils;
        private String errorPage = "errorPage";
    
        // 生成授权链接
        @RequestMapping("/authorizedUrl")
        public String authorizedUrl() {
            System.out.println(weiXinUtils.getAuthorizedUrl());
            return "redirect:" + weiXinUtils.getAuthorizedUrl();   //重定向到微信的开放平台地址
        }
    
        // 微信授权回调地址
        @RequestMapping("/callback")
        public String callback(String code, HttpServletRequest request) {
            // 1.使用Code 获取 access_token
            String accessTokenUrl = weiXinUtils.getAccessTokenUrl(code);
            JSONObject resultAccessToken = HttpClientUtils.httpGet(accessTokenUrl);
            boolean containsKey = resultAccessToken.containsKey("errcode");
    
            if (containsKey) {
                request.setAttribute("errorMsg", "系统错误!");
                return errorPage;
            }
            // 2.使用access_token获取用户信息
            String accessToken = resultAccessToken.getString("access_token");
            String openid = resultAccessToken.getString("openid");
            // 3.拉取用户信息(需scope为 snsapi_userinfo)
            String userInfoUrl = weiXinUtils.getUserInfo(accessToken, openid);
            JSONObject userInfoResult = HttpClientUtils.httpGet(userInfoUrl);
            System.out.println("userInfoResult:" + userInfoResult);
            request.setAttribute("nickname", userInfoResult.getString("nickname"));
            request.setAttribute("city", userInfoResult.getString("city"));
            request.setAttribute("headimgurl", userInfoResult.getString("headimgurl"));
            return "info";
        }
    
    }

    Base:

    import org.springframework.stereotype.Component;
    
    import com.itmayiedu.utils.Constants;
    
    @Component
    public class BaseApiService {
    
        public ResponseBase setResultError(Integer code, String msg) {
            return setResult(code, msg, null);
        }
    
        // 返回错误,可以传msg
        public ResponseBase setResultError(String msg) {
            return setResult(Constants.HTTP_RES_CODE_500, msg, null);
        }
    
        // 返回成功,可以传data值
        public ResponseBase setResultSuccessData(Object data) {
            return setResult(Constants.HTTP_RES_CODE_200, Constants.HTTP_RES_CODE_200_VALUE, data);
        }
    
        public ResponseBase setResultSuccessData(Integer code, Object data) {
            return setResult(code, Constants.HTTP_RES_CODE_200_VALUE, data);
        }
    
        // 返回成功,沒有data值
        public ResponseBase setResultSuccess() {
            return setResult(Constants.HTTP_RES_CODE_200, Constants.HTTP_RES_CODE_200_VALUE, null);
        }
    
        // 返回成功,沒有data值
        public ResponseBase setResultSuccess(String msg) {
            return setResult(Constants.HTTP_RES_CODE_200, msg, null);
        }
    
        // 通用封装
        public ResponseBase setResult(Integer code, String msg, Object data) {
            return new ResponseBase(code, msg, data);
        }
    
    }
    import lombok.Getter;
    import lombok.Setter;
    import lombok.extern.slf4j.Slf4j;
    
    @Getter
    @Setter
    @Slf4j
    public class ResponseBase {
    
        private Integer rtnCode;
        private String msg;
        private Object data;
    
        public ResponseBase() {
    
        }
    
        public ResponseBase(Integer rtnCode, String msg, Object data) {
            super();
            this.rtnCode = rtnCode;
            this.msg = msg;
            this.data = data;
        }
    
        public static void main(String[] args) {
            ResponseBase responseBase = new ResponseBase();
            responseBase.setData("123456");
            responseBase.setMsg("success");
            responseBase.setRtnCode(200);
            System.out.println(responseBase.toString());
            log.info("itmayiedu...");
        }
    
        @Override
        public String toString() {
            return "ResponseBase [rtnCode=" + rtnCode + ", msg=" + msg + ", data=" + data + "]";
        }
    
    }

    Entity:

    public class AppEntity {
    
        private long id;
        private String appId;
        private String appName;
        private String appSecret;
        private String accessToken;
        private String redirectUri;
        private int isFlag;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getAppId() {
            return appId;
        }
    
        public void setAppId(String appId) {
            this.appId = appId;
        }
    
        public String getAppName() {
            return appName;
        }
    
    
        public void setAppName(String appName) {
            this.appName = appName;
        }
    
        public String getAppSecret() {
            return appSecret;
        }
    
    
        public void setAppSecret(String appSecret) {
            this.appSecret = appSecret;
        }
    
        public int getIsFlag() {
            return isFlag;
        }
    
    
        public void setIsFlag(int isFlag) {
            this.isFlag = isFlag;
        }
    
        public String getAccessToken() {
            return accessToken;
        }
    
        
        public void setAccessToken(String accessToken) {
            this.accessToken = accessToken;
        }
    
        public String getRedirectUri() {
            return redirectUri;
        }
    
    
        public void setRedirectUri(String redirectUri) {
            this.redirectUri = redirectUri;
        }
    
    }
    import lombok.Getter;
    import lombok.Setter;
    import lombok.extern.slf4j.Slf4j;
    
    @Getter
    @Setter
    @Slf4j
    public class ResponseBase {
    
        private Integer rtnCode;
        private String msg;
        private Object data;
    
        public ResponseBase() {
    
        }
    
        public ResponseBase(Integer rtnCode, String msg, Object data) {
            super();
            this.rtnCode = rtnCode;
            this.msg = msg;
            this.data = data;
        }
    
        public static void main(String[] args) {
            ResponseBase responseBase = new ResponseBase();
            responseBase.setData("123456");
            responseBase.setMsg("success");
            responseBase.setRtnCode(200);
            System.out.println(responseBase.toString());
            log.info("itmayiedu...");
        }
    
        @Override
        public String toString() {
            return "ResponseBase [rtnCode=" + rtnCode + ", msg=" + msg + ", data=" + data + "]";
        }
    
    }

    Util:

    public interface Constants {
        // 响应请求成功
        String HTTP_RES_CODE_200_VALUE = "success";
        // 系统错误
        String HTTP_RES_CODE_500_VALUE = "fial";
        // 响应请求成功code
        Integer HTTP_RES_CODE_200 = 200;
        // 系统错误
        Integer HTTP_RES_CODE_500 = 500;
        // 未关联QQ账号
        Integer HTTP_RES_CODE_201 = 201;
        // 发送邮件
        String MSG_EMAIL = "email";
        // 会员token
        String TOKEN_MEMBER = "TOKEN_MEMBER";
        // 支付token
        String TOKEN_PAY = "TOKEN_pay";
        // 支付成功
        String PAY_SUCCESS = "success";
        // 支付白
        String PAY_FAIL = "fail";
        // 用户有效期 90天
        Long TOKEN_MEMBER_TIME = (long) (60 * 60 * 24 * 90);
        int COOKIE_TOKEN_MEMBER_TIME = (60 * 60 * 24 * 90);
        Long PAY_TOKEN_MEMBER_TIME = (long) (60 * 15);
        // cookie 会员 totoken 名称
        String COOKIE_MEMBER_TOKEN = "cookie_member_token";
    
    }
    import java.io.IOException;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.alibaba.fastjson.JSONObject;
    
    
    public class HttpClientUtils {
        private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录
    
        private static RequestConfig requestConfig = null;
    
        static {
            // 设置请求和传输超时时间
            requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
        }
    
    
        public static JSONObject httpPost(String url, JSONObject jsonParam) {
            // post请求返回结果
            CloseableHttpClient httpClient = HttpClients.createDefault();
            JSONObject jsonResult = null;
            HttpPost httpPost = new HttpPost(url);
            // 设置请求和传输超时时间
            httpPost.setConfig(requestConfig);
            try {
                if (null != jsonParam) {
                    // 解决中文乱码问题
                    StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                    entity.setContentEncoding("UTF-8");
                    entity.setContentType("application/json");
                    httpPost.setEntity(entity);
                }
                CloseableHttpResponse result = httpClient.execute(httpPost);
                // 请求发送成功,并得到响应
                if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    String str = "";
                    try {
                        // 读取服务器返回过来的json字符串数据
                        str = EntityUtils.toString(result.getEntity(), "utf-8");
                        // 把json字符串转换成json对象
                        jsonResult = JSONObject.parseObject(str);
                    } catch (Exception e) {
                        logger.error("post请求提交失败:" + url, e);
                    }
                }
            } catch (IOException e) {
                logger.error("post请求提交失败:" + url, e);
            } finally {
                httpPost.releaseConnection();
            }
            return jsonResult;
        }
    
    
        public static JSONObject httpPost(String url, String strParam) {
            // post请求返回结果
            CloseableHttpClient httpClient = HttpClients.createDefault();
            JSONObject jsonResult = null;
            HttpPost httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            try {
                if (null != strParam) {
                    // 解决中文乱码问题
                    StringEntity entity = new StringEntity(strParam, "utf-8");
                    entity.setContentEncoding("UTF-8");
                    entity.setContentType("application/x-www-form-urlencoded");
                    httpPost.setEntity(entity);
                }
                CloseableHttpResponse result = httpClient.execute(httpPost);
                // 请求发送成功,并得到响应
                if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    String str = "";
                    try {
                        // 读取服务器返回过来的json字符串数据
                        str = EntityUtils.toString(result.getEntity(), "utf-8");
                        // 把json字符串转换成json对象
                        jsonResult = JSONObject.parseObject(str);
                    } catch (Exception e) {
                        logger.error("post请求提交失败:" + url, e);
                    }
                }
            } catch (IOException e) {
                logger.error("post请求提交失败:" + url, e);
            } finally {
                httpPost.releaseConnection();
            }
            return jsonResult;
        }
    
    
        public static JSONObject httpGet(String url) {
            // get请求返回结果
            JSONObject jsonResult = null;
            CloseableHttpClient client = HttpClients.createDefault();
            // 发送get请求
            HttpGet request = new HttpGet(url);
            request.setConfig(requestConfig);
            try {
                CloseableHttpResponse response = client.execute(request);
    
                // 请求发送成功,并得到响应
                if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    // 读取服务器返回过来的json字符串数据
                    HttpEntity entity = response.getEntity();
                    String strResult = EntityUtils.toString(entity, "utf-8");
                    // 把json字符串转换成json对象
                    jsonResult = JSONObject.parseObject(strResult);
                } else {
                    logger.error("get请求提交失败:" + url);
                }
            } catch (IOException e) {
                logger.error("get请求提交失败:" + url, e);
            } finally {
                request.releaseConnection();
            }
            return jsonResult;
        }
    
    }
    import java.net.URLEncoder;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    
    @Component
    public class WeiXinUtils {
        @Value("${appid}")
        private String appId;
        @Value("${secret}")
        private String secret;
        @Value("${redirecturi}")
        private String redirectUri;
        @Value("${authorizedUrl}")
        private String authorizedUrl;
        @Value("${access_token}")
        private String accessToken;
        @Value("${userinfo}")
        private String userinfo;
    
        public String getAuthorizedUrl() {
            return authorizedUrl.replace("APPID", appId).replace("REDIRECT_URI", URLEncoder.encode(redirectUri));
        }
    
        public String getAccessTokenUrl(String code) {
            return accessToken.replace("APPID", appId).replace("SECRET", secret).replace("CODE", code);
        }
    
        public String getUserInfo(String accessToken, String openId) {
            return userinfo.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        }
    
    }

    启动类:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class AppOauth {
    
        public static void main(String[] args) {
            SpringApplication.run(AppOauth.class, args);
        }
    
    }
  • 相关阅读:
    Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986
    Calendar的用法
    spring boot+mybatis+mysql增删改查分页
    HIVE-利用ow_number() OVER(PARTITION BY)函数介绍求TOP-K
    Sqoop-从hive导出分区表到MySQL
    Sqoop--Free-form Query Imports 自由查询模式下$CONDITIONS关键字的作用
    HIVE-执行hive的几种方式,和把HIVE保存到本地的几种方式
    HIVE-分桶表的详解和创建实例
    HIVE-几道经典的hive题目
    HIVE-如何查看执行日志
  • 原文地址:https://www.cnblogs.com/toov5/p/10317732.html
Copyright © 2020-2023  润新知