第三方登录 ---Github

背景:最近一直在做第三方平台登录的相关工作,由于要接入这些平台需要涉及到各个平台的开发者账号的申请工作,而企业级的开发者账号申请就更麻烦了,但是github的开发者账号就很简单,所以当时就以Github作为示例了。

整个第三方平台的开发流程图如下

名词解释

APP_ID在第三方平台申请的APP标识
APP_SECRETE在第三方平台申请的APP秘钥(注意保密)
CODE预授权码
ACCESS_TOKEN授权码
OPEN_ID第三方平台的用户ID

流程图文字描述:

首先用户在页面选择触发具体的第三方平台登录,此时我们的应用系统要携带我们的APP_ID+回调地址访问第三方平台的授权页面,当用户在第三方平台成功的登录后,第三方平台会自动携带CODE调用回调地址将用户重定向到我们的应该系统中,此时我们在使用CODE+APP_SECRETE调用第三方平台提供的接口,就可以得到ACCESS_TOKEN了,最后再通过这ACCESS_TOKEN调用第三方平台提供的接口即可得到用户的OPEN_ID(还可以取到其他的用户信息,比如:用户名、图像等).

注意:
1.在跳转到第三方的授权登录页面时,有的第三方平台会检查APP_ID和回调地址是否与开发者账号中配置的应用信息是否一致,所以请认真配置

2.第三方平台的处理流程在细节上差异很大,但是总体流程都是大同小异的,文末将附上相关平台的接口链接


下面开始正式搭建系统

1.首先在Github上配置相关应用信息

  登录Github --> settings --> Applications --> Developer settings

然按照表单内容填写即可

 注册完成后就可以看到应用的相关信息了

到这里我们的准备工作就完成了,下面开始写代码,首先配置pom.xml引入相关的依赖包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>auth.demo</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.scribe</groupId>
            <artifactId>scribe</artifactId>
            <version>1.3.7</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.41</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

代码结构如下,主要的文件已经用红圈圈出了

具体步骤:

1.新建index.html文件,主要负责点击后,将请求定位到我们的登录页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1><a href="http:/127.0.0.1:12345/login/github">Github登录</a></h1>
</body>
</html>

2.增加GithubAuthController.java

package qn.auth.demo.demo.github.controller;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import qn.auth.demo.demo.github.service.GithubAuthService;

import javax.servlet.http.HttpServletResponse;

/**
 * @author callmevvv
 * @date 2019/9/21
 * @description
 */
@Slf4j
@Controller
@RequestMapping("/github")
@AllArgsConstructor
public class GithubAuthController {
    /**
     * github认证的业务处理类
     */
    private GithubAuthService githubAuthService;

    /**
     * 跳转到github的授权登录页面
     * @param response
     * @throws Exception
     */
    @GetMapping("/login")
    public void showLoginPage(HttpServletResponse response) throws Exception {
        String path = githubAuthService.getGithubAuthPath();
        response.sendRedirect(path);
    }

    /**
     * 在github页面登录成功后,github会回调这个
     * @param code
     * @return
     */
    @GetMapping(value = "/callback")
    @ResponseBody
    public String callback(@RequestParam(value = "code") String code) {
        return githubAuthService.callback(code);
    }
}

3.新建GithubAuthService.java接口

package qn.auth.demo.demo.github.service;

/**
 * @author callmevvv
 * @date 2019/9/21
 * @description
 */
public interface GithubAuthService {

    /**
     * 获取github的授权地址
     * @return
     */
    String getGithubAuthPath();

    /**
     * 在github页面登录成功后,回调的处理方法
     * @param code
     * @return
     */
    String callback(String code);
}

 4.增加GithubAuthServiceImpl.java接口实现类

package qn.auth.demo.demo.github.service.impl;

import com.sun.deploy.net.HttpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.ResourceHttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import qn.auth.demo.demo.github.service.GithubAuthService;

import javax.xml.transform.Source;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * @author callmevvv
 * @date 2019/9/21
 * @description
 */
@Slf4j
@Service
public class GithubAuthServiceImpl implements GithubAuthService {
    /**
     * github的授权地址
     */
    private final static String GITHUB_CODE_URL = "https://github.com/login/oauth/authorize?client_id=%s&redirect_uri=%s&state=%s";

    /**
     * 获取github用户ACCESS_TOKEN地址
     */
    private final static String GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token?client_id=%s&client_secret=%s&code=%s";

    /**
     * 获取github用户信息
     */
    private final static String GITHUB_USER_URL = "https://api.github.com/user?access_token=%s";

    /**
     * 服务器github的客户端ID
     */
    private final static String CLIENT_ID = "Iv1.xxxxxxxx";

    /**
     * 应用秘钥
     */
    private final static String CLIENT_SECRETE = "c26xxxxxxxxxxxxxxxxxxxxx4e5";

    /**
     * github的回调地址
     */
    private final static String REDIRECT_URL = "http://127.0.0.1:12345/github/callback";

    /**
     *
     */
    private final static String ACCESS_TOKEN_NAME = "access_token";

    /**
     * 该字段的值会回传回来
     */
    private final static String STATE = "true";
    /**
     *  本系统访问github登录页面的URL地址
     */
    static String APP_GITHUB_CODE_URL = String.format(GITHUB_CODE_URL,CLIENT_ID,REDIRECT_URL,STATE);

    @Override
    public String getGithubAuthPath() {
        return APP_GITHUB_CODE_URL;
    }

    @Override
    public String callback(String code) {
        String accessToken = getAccessToken(code);
        return getOpenId(accessToken);
    }
    public String getAccessToken(String code) {
        String url = String.format(GITHUB_TOKEN_URL,CLIENT_ID,CLIENT_SECRETE,code);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();

        String resp = getRestTemplate().getForObject(uri, String.class);
        if (resp.contains(ACCESS_TOKEN_NAME)) {
            Map<String, String> map = getParam(resp);
            String access_token = map.get(ACCESS_TOKEN_NAME);
            return access_token;
        } else {
            throw new RuntimeException(resp);
        }

    }

    public String getOpenId(String accessToken) {
        String url = String.format(GITHUB_USER_URL,accessToken);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();
        String resp = getRestTemplate().getForObject(uri, String.class);
        log.error("getAccessToken resp = "+resp);
        return  resp;
    }


    public RestTemplate getRestTemplate() {// 手动添加
        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setReadTimeout(120000);
        List<HttpMessageConverter<?>> messageConverters = new LinkedList<>();
        messageConverters.add(new ByteArrayHttpMessageConverter());
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        messageConverters.add(new ResourceHttpMessageConverter());
        messageConverters.add(new SourceHttpMessageConverter<Source>());
        messageConverters.add(new AllEncompassingFormHttpMessageConverter());
        messageConverters.add(new MappingJackson2HttpMessageConverter());
        RestTemplate restTemplate = new RestTemplate(messageConverters);
        restTemplate.setRequestFactory(requestFactory);
        return restTemplate;
    }

    private Map<String, String> getParam(String string) {
        Map<String, String> map = new HashMap();
        String[] kvArray = string.split("&");
        for (int i = 0; i < kvArray.length; i++) {
            String[] kv = kvArray[i].split("=");
            if(kv != null){
                if(kv.length == 1){
                    map.put(kv[0], null);
                }else if(kv.length == 2){
                    map.put(kv[0], kv[1]);
                }
            }
        }
        return map;
    }
}

到这里代码就已经写完了,下面只需要启动程序,然后访问index.html文件即可

 点击后将会跳转到github的登录页面,注意看上面的地址

最后在github登录成功后,将会得到下面的类似结果

这样我们就得到了当前登录github用户的用户信息了,到这里就大功告成了 。


相关资料

QQ开发文档

微博开发文档

微信开发文档

企业微信

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OkHttp是一个流行的开源的HTTP客户端,它可以用于发送和接收HTTP请求。要实现GitHub第三方登录,我们可以使用OkHttp向GitHub的认证服务器发送请求,并获取授权码或访问令牌。 下面是一个用OkHttp实现GitHub第三方登录的简单的步骤: 1. 首先,我们需要在GitHub开发者平台注册一个应用程序,获得Client ID和Client Secret。这些凭证将用于向GitHub认证服务器证明我们的应用程序的身份。 2. 在应用程序中,创建一个OkHttpClient实例并实例化一个Request对象。Request对象应该包含登录请求的URL、请求方法(一般是GET或POST)、请求头(包括Accept和User-Agent等)以及需要的参数(如Client ID、Client Secret和一些其他参数)。 3. 调用OkHttpClient的newCall方法并传入Request对象来创建Call对象。 4. 调用Call对象的execute方法来发送请求并获取响应。得到的响应是一个Response对象。 5. 从Response对象中获取响应的内容,可能是JSON格式的数据。如果响应中包含授权码或访问令牌,我们可以将其用于后续的访问。 6. 进行登录验证和其他操作。根据响应内容和需要,可以使用OkHttp继续发送请求并处理响应。 需要注意的是,此处的步骤是简化的,并且可能因GitHub的认证流程而有所不同。在实际的应用程序中,还需要处理认证过程中的错误、重试机制、OAuth协议的授权流程等相关问题。 总结来说,使用OkHttp实现GitHub第三方登录需要创建OkHttpClient和Request对象,发送请求并获取响应,然后根据需要处理响应,获取授权码或访问令牌。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值