Github授权登录

19 年 9 月 8 日 星期日
887 字
5 分钟

Github第三方授权登录

创建一个OAuth App

  • 登录Github,在用户头像的位置,依次进入:

    -> Settings/ Developer settings /OAuth Apps

    点击New OAuth App

  • 新建OAuth App

    • Application name,自定义的名字
    • Homepage URL,随便写个
    • Application description,描述,自定义写
    • Authorization callback URL,请求github后回调的url,认真写个,不过以后能改
  • 编辑OAuth App信息

    • 这是你的客户端id和密钥
    • 这是头像和信息,我这里回调地址写的本地地址,项目上线后再改成公网地址

我的回调地址:http://localhost:8888/github/codeCallback

授权流程

流程图

实现

  • ①调用github授权的api,传递自己的id、scope(是需要的信息,比如user),用controller跳转或直接写在页面的a标签里。

GET方式,apihttps://github.com/login/oauth/authorize 必带参数client_id:客户端id scope:需要请求的信息,user repo 返回值code:用于下一步请求access_token state:这一步请求时的可选参数,是自己定义的一串字符串 返回值实例http://localhost:8888/github/codeCallback?code=d367eeabc1e0614c3a58&state=shirtiny2011054984anro

更多参数详情,参照官方文档。

Controller(或直接写在页面里)

java
@Value("${Github_Oauth_Authorize_FullUrl}")
private String Authorize_URL;

//请求Github登录授权
    @GetMapping(value = "/github/loginWithGithub")
    public String loginWithGithub() throws IOException {
       //发送请求
        return "redirect:"+Authorize_URL;
    }
  • ②处理github响应的code、state,传给github的access_token api,拿到响应后的令牌

POST方式,api: https://github.com/login/oauth/access_token

必带参数: client_id:客户端id client_secret:客户端密钥 code:上一步github返回的code state:上一步github返回的state,如果有的话 返回值: access_token:用于下一步请求用户信息 token_type:令牌类型 返回值实例: access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer

服务

java
 @Override
    public String getAccessToken(String code, String state) throws IOException {

        OkHttpClient httpClient = new OkHttpClient();
        //json MediaType
        final MediaType MediaType_JSON= MediaType.get("application/json; charset=utf-8");
        //需要实体类对象 然后转成json字符串
        githubOauth.setCode(code);
        githubOauth.setState(state);
//        githubOauth.setRedirect_uri("http://localhost:8888/github/codeCallback");
        String json = JSON.toJSONString(githubOauth);
        //创建请求体
        RequestBody requestBody = RequestBody.create(MediaType_JSON, json);
        //建立请求,post方式调用
        Request request= new Request.Builder().url(url_AccessToken).post(requestBody).build();
        //执行请求
        Response response = httpClient.newCall(request).execute();
        //拿到响应结果
        String tokenAndType = response.body().string();
        System.out.println("得到通关令牌和令牌类型:"+tokenAndType);
        return tokenAndType;
    }
  • ③将响应的令牌传给github的user api,获取用户信息

GET方式,apihttps://api.github.com/user 必带参数: access_token:上一步github返回的access_token 返回值: 用户信息,一个json格式的字符串,建议建一个实体类,方便存储这些信息。

服务

java
@Override
    public String getUserInfoJson(String access_token) throws IOException {
        //根据github回调code取用户信息,需要post请求
        OkHttpClient httpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url_User+"?access_token="+access_token).build();
        Response response = httpClient.newCall(request).execute();
        //得到响应的json字符串
        String userInfoJson = response.body().string();
        System.out.println("用令牌调用github的user_api,得到github用户信息:"+userInfoJson);
        return userInfoJson;
    }

完整Controller

java
package cn.shirtiny.community.SHcommunity.Controller;
import ...

@Controller
public class LoginController {

    @Autowired
    private IGithubService githubService;
    @Value("${Github_Oauth_Authorize_FullUrl}")
    private String Authorize_URL;


    //请求Github登录授权
    @GetMapping(value = "/github/loginWithGithub")
    public String loginWithGithub() throws IOException {
       //发送请求
        return "redirect:"+Authorize_URL;
    }

    //github那边处理完登录、注册、授权,之后会回调设置的url,我设置的回调地址是:http://localhost:8888/github/codeCallback
    @GetMapping(value = "/github/codeCallback")//接收github返回的参数值,样例:http://callbackurl?code=...&state=...
    public String  githubCodeCallback(String code,String state
            , HttpServletRequest httpServletRequest) throws IOException {
        String tokenAndType = githubService.getAccessToken(code, state);//tokenAndType样例access_token=e72e16c7e42f292c6912e7710c838347ae178b4a&token_type=bearer
        //把tokenAndType根据&号分割,取第一个,再根据=号分割,取第二个,得到token
        String accessToken= tokenAndType.split("&")[0].split("=")[1];
        String userInfoJson = githubService.getUserInfoJson(accessToken);
        GithubUserInfo userInfo = JSON.parseObject(userInfoJson, GithubUserInfo.class);
        System.out.println(userInfo);
        httpServletRequest.getSession().setAttribute("userinfo",userInfo);
        return "redirect:/index";
    }
}

属性配置文件

*为保密信息

properties
Github_Oauth_Authorize_Url=https://github.com/login/oauth/authorize
Github_Oauth_Client_Id=***********
Github_Oauth_Client_Secret=***********
Github_Oauth_Scope=user
Github_Oauth_State=**********
Github_Oauth_AccessToken_Url=https://github.com/login/oauth/access_token
Github_Oauth_Authorize_FullUrl=https://github.com/login/oauth/authorize?client_id=*********&scope=user&state=***********
Github_Oauth_User_Url=https://api.github.com/user

首页页面

html
<!-- 右下拉框-->
<ul class="nav navbar-nav navbar-right">
  <!-- if判断 标签内有效-->
  <li><a href="/github/loginWithGithub" th:if="${session.userinfo==null}">登录</a></li>
  <li class="dropdown" th:if="${session.userinfo!=null}">
    <a
      href="#"
      class="dropdown-toggle"
      data-toggle="dropdown"
      role="button"
      aria-haspopup="true"
      aria-expanded="false"
      ><span th:text="${session.userinfo.getLogin()}"></span>个人中心 <span class="caret"></span
    ></a>
    <ul class="dropdown-menu">
      <li><a href="#">Action</a></li>
      <li><a href="#">Another action</a></li>
      <li><a href="#">Something else here</a></li>
      <li role="separator" class="divider"></li>
      <li><a href="#">Separated link</a></li>
    </ul>
  </li>
</ul>

官方文档

文章标题:Github授权登录

文章作者:shirtiny

文章链接:https://kizamu.anror.com/posts/github-sso[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。