1.什么是OAuth2.0
- OAuth: OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
- OAuth2.0:对于用户相关的OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权
- 官方版流程:
(A)用户打开客户端以后,客户端要求用户给予授权。
(B)用户同意给予客户端授权。
(C)客户端使用上一步获得的授权,向认证服务器申请令牌。
(D)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
(E)客户端使用令牌,向资源服务器申请获取资源。
(F)资源服务器确认令牌无误,同意向客户端开放资源。
2、微博登陆准备工作
- 进入微博开放平台
2.登陆微博,进入微连接,选择网站接入
点击已经创建好的应用
填写授权回调页的地址
3、微博登陆测试
现在回到程序了,开始开发吧…
- 引导用户到下面的地址
https://api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
https://api.weibo.com/oauth2/authorize?client_id=1288161722&response_type=code&redirect_uri=http://passport.gmall.com/vlogin
response_type=code,这里不用动
这个是我做的登录页面,点击微博logo
然后跳转到这里
登录后,会跳转到授权回调页的地址redirect_uri
,访问http://passport.gmall.com/vlogin
,这里填写具体自己的地址
下面是我的是vlogin接口的代码,只提供登录的核心代码
@RequestMapping("/vlogin")
public String vlogin(String code, HttpServletRequest request) {
//授权码换取access_token,code是授权后回调地址带回的,就是response_type=code
//https://api.weibo.com/oauth2/authorize?client_id=1288161722&response_type=code&redirect_uri=http://passport.gmall.com/vlogin
String access_token = getAccess_token(code);
//access_token换区用户信息
Map<String, Object> userMap = new HashMap<>();
String uid = "";
String accessTokenStr = "";
if (StringUtils.isNotBlank(access_token)) {
//access_token是json串,实际的access_token在里面,取出来就是accessTokenStr,uid也在json串里面
Map<String, Object> accessMap = JSON.parseObject(access_token, Map.class);
accessTokenStr = (String) accessMap.get("access_token");
uid = (String) accessMap.get("uid");
String access_token_get_msg_url = "https://api.weibo.com/2/users/show.json?access_token=" + accessTokenStr + "&uid=" + uid;
String userMsg = HttpclientUtil.doGet(access_token_get_msg_url);
//用户信息
userMap = JSON.parseObject(userMsg, Map.class);
} else {
//access_token为空,回到登录页面
return "redirect:/index";
}
//将用户信息userMap保存数据库,用户类型设置为微博用户
//生成jwt的token,并重定向到XXX页面,同时携带该token
//我这里重定向到首页,一般来说是返回到上个页面
return "redirect:http://search.gmall.com/index?token=" + token
}
这里是用授权码获取access_token,只有access_token才能获取用户信息
private String getAccess_token(String code) {
String url = "https://api.weibo.com/oauth2/access_token?"; //下面两张图片中可以看到
Map<String, String> paramMap = new HashMap<>();
paramMap.put("client_id", "自己的"); //上面有提到
paramMap.put("client_secret", "自己的"); //上面有提到
paramMap.put("grant_type", "authorization_code");
paramMap.put("redirect_uri", "http://passport.gmall.com/vlogin"); //回调地址
paramMap.put("code", code);
String access_token = HttpclientUtil.doPost(url, paramMap);
return access_token;
}
附上HttpclientUtil:觉得不好的可以自己优化一下
/**
* @ClassName HttpclientUtil
* @Description 简单实现get和post请求
* @Author zeny
* @Date 2020/2/4 13:30
* @Version 1.0
*/
public class HttpclientUtil {
public static String doGet(String url) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http GET请求
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = null;
try {
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
httpclient.close();
return result;
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return null;
}
public static String doPost(String url, Map<String, String> paramMap) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
// 创建http Post请求
HttpPost httpPost = new HttpPost(url);
CloseableHttpResponse response = null;
try {
List<BasicNameValuePair> list = new ArrayList<>();
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
HttpEntity httpEntity = new UrlEncodedFormEntity(list, "utf-8");
httpPost.setEntity(httpEntity);
// 执行请求
response = httpclient.execute(httpPost);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
EntityUtils.consume(entity);
httpclient.close();
return result;
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return null;
}
}