1.OAuth含义
OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
OAuth2.0 :对于用户相关的 OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。
2.授权流程
1.第三方应用向用户申请请求认证。
2.用户授权输入自己的社交账号密码。
3.使用上一步授权,进行认证。
4.认证通过,返回访问令牌。
5.使用访问令牌,获取开放保护信息。
6.认证令牌,返回受保护的信息。
使用code换取accessToken。code只能用一次
同一个用户的accessToken一段时间是不会变化,即使多次获取还是不变。
3.微博第三方登录
1.微博设置
进入微博开放平台-->网站接入-->立即接入-->填写应用名称-->创建。(应用分类就是网页应用)。
一般微博审核需要两天左右、创建好的应用会在我的应用中显示,点击应用里的应用信息会有应用的基本信息。里面的App Key和App Secret会在后续中用到。在高级信息中需要填写授权回调页和取消授权回调页。
2.接入步骤
引导用户到微博的认证地址:https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
client_id:微博网站接入提供的 APP KEY;
redirect_uri:认证后重定向的地址;
用户同意授权重定向到上面设置的地址并携带 code:填写的回调地址带上code
使用 code 请求微博提供的地址换取 access_token:https://api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
client_id:APP KEY;
client_secret:APP SECRET;
redirect_uri:认证后重定向的地址(回调地址)
code:第二步返回的 code 值
3.代码示例
可以将微博开放获取到的信息存到数据库中,方便以后操作。
4.Gitee登录
1.Gitee设置
点击个人头像下的设置-->数据管理下的第三方应用-->创建应用-->填写授权回调页-->可以勾选权限信息(gitee开放可以获得的信息),创建完可以看到Client ID和Client Secret。
2.Gitee接入步骤
OAuth2 获取 AccessToken 认证步骤
1.应用通过 浏览器 或 Webview 将用户引导到码云三方认证页面上( GET请求 )https://gitee.com/oauth/authorizeclient_id{client_id}&redirect_uri{redirect_uri}&response_type=code
2.用户对应用进行授权
注意: 如果之前已经授权过的需要跳过授权页面,需要在上面第一步的 URL 加上 scope 参数,且 scope 的值需要和用户上次授权的勾选的一致。如用户在上次授权了user_info、projects以及pull_requests。则步骤A 中 GET 请求应为:
3.码云认证服务器通过回调地址{redirect_uri}将 用户授权码 传递给 应用服务器 或者直接在 Webview 中跳转到携带 用户授权码的回调地址上,Webview 直接获取code即可({redirect_uri}?code=abc&state=xyz)
4.应用服务器 或 Webview 使用 access_token API 向 码云认证服务器发送post请求传入 用户授权码 以及 回调地址( POST请求 )注:请求过程建议将 client_secret 放在 Body 中传值,以保证数据安全。
5.码云认证服务器返回 access_token
应用通过 access_token 访问 Open API 使用用户数据。
6.当 access_token 过期后(有效期为一天),你可以通过以下 refresh_token 方式重新获取 access_token( POST请求 )
https://gitee.com/oauth/token?grant_type=refresh_token&refresh_token={refresh_token}
3.代码示例
@GetMapping("/oauth2/gitee/success")
public String gitee(@RequestParam("code") String code,HttpSession session) throws Exception {
Map<String, String> map = new HashMap<>();
map.put("client_id", "client_id");
map.put("client_secret", "client_secret");
map.put("grant_type", "authorization_code");
map.put("code", code);
map.put("redirect_uri", "redirect_uri");
HttpResponse response = HttpUtils.doPost("https://gitee.com", "/oauth/token", "post", new HashMap<String, String>(), map, new HashMap<String, String>());
//处理
if (response.getStatusLine().getStatusCode() == 200) {
//3.调用 member 远程接口进行 oauth 登录,登录成功则转发至首页并携带返回用户信息,否则转发至登录页
String json = EntityUtils.toString(response.getEntity());
//socialUserTo没有id这个返回值
SocialUserVo socialUserVo = JSON.parseObject(json, new TypeReference<SocialUserVo>() {
});
// 拿着 accessToken 查询用户信息
if (socialUserVo != null && (!StringUtils.isEmpty(socialUserVo.getAccessToken()))) {
Map<String, String> queryAccessToken = new HashMap<>();
queryAccessToken.put("access_token", socialUserVo.getAccessToken());
Map<String, String> queryHeader = new HashMap<>();
queryHeader.put("Content-Type", "application/json;charset=UTF-8");
//发送请求
//https://gitee.com/api/v5/user?access_token={access_token}
HttpResponse response1 = HttpUtils.doGet("https://gitee.com", "/api/v5/user", "get", queryHeader, queryAccessToken);
;
if (response1.getStatusLine().getStatusCode() == 200) {
//请求成功
String json1 = EntityUtils.toString(response1.getEntity());
//获取 user_info 的 id
//转成 SocialUserTo 方便调用服务
SocialUserVo socialUserVo1 = JSON.parseObject(json1, new TypeReference<SocialUserVo>() {
});
socialUserVo1.setAccessToken(socialUserVo.getAccessToken());
socialUserVo1.setExpiresIn(socialUserVo.getExpiresIn());
System.out.println("带id====" + socialUserVo1.toString());
// TODO 社交帐号登录与注册为一体
// ================远程调用登录==================
System.out.println(socialUserVo.toString());
R login = memberFeignService.GiteeLogin(socialUserVo1);
//2.1 远程调用成功,返回首页并携带用户信息
if (login.getCode() == 0) {
MemberRespVo memberEntity = login.getData("data", new TypeReference<MemberRespVo>() {
});
session.setAttribute(AuthConstant.LOGIN_USER, memberEntity);
System.out.println("用户信息:" + memberEntity.toString());
return "redirect:";
} else {
//2.2 否则返回登录页
return "redirect:";
}
} else {
return "redirect:";
}
}
}
return "redirect:";
}