微信一鍵登陸(微信OAuth2.0)

1.註冊微信開放平臺https://open.weixin.qq.com,必定要清楚微信開放平臺和微信公衆平臺是分別獨立的,不能共用。web

2.登陸進入——管理中心,網站應用,建立網站應用。填寫申請,企業還要蓋章,而後設置域名,最後交300元保護費。成功經過驗證。得到appid和appSecret兩個參數。
3.如今能夠在web端裏寫登陸控制器了。
4.微信網站登陸的文檔在https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=41ab5f757248bbbdcc2aad1a6d52b49fdc19579e&lang=zh_CN。

數據庫

以上前3步是公司去微信那邊註冊用的。主要是獲取兩個參數 appid (應用惟一標識)和 appsecret (是應用接口使用密鑰) 還有就是指定咱們註冊時,api

對應的域名,方便咱們之後進行域名映射跳轉。 第4不是微信官方文檔咱們的會和微信交互3次,這三個鏈接都是從文檔上拿的記得好好看。瀏覽器

總體流程就是:微信

1. 第三方發起微信受權登陸請求,微信用戶容許受權第三方應用後,微信會拉起應用或重定向到第三方網站,而且帶上受權臨時票據code參數;
2. 經過code參數加上AppID和AppSecret等,經過API換取access_token;
3. 經過access_token進行接口調用,獲取用戶基本數據資源或幫助用戶實現基本操做。app

==貼代碼微信公衆平臺

1.第一步ide

 

**
*@ClassName 讀取微信配置文件中的參數
*@Description TODD
*@AUTHOR sh-wangbs
*@Date 2019/1/3115:00
*@Version 1.0
**/
@Configuration
@PropertySource(value = "classpath:application.properties")
@Data
public class WeChatConfig {
//開放平臺appid
@Value("${wxopen.appid}")
private String openAppid;
//開放平臺appsecret
@Value("${wxopen.appsecret}")
private String openAppsecret;
//重定向第三方平臺的地址
@Value("${wxopen.redirect_url}")
private String openRedirectUrl;
//微信開放平臺二維碼鏈接(從微信官方文檔拿的第一個鏈接)
private final static String OPEN_QRCODE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect";
// 開放平臺獲取access_token地址(從微信官方文檔拿的第二個鏈接)
private final static String OPEN_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
//獲取用戶信息(從微信官方文檔拿的第三個鏈接)
private final static String OPEN_USER_INFO_URL ="https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN";

public static String getOpenUserInfoUrl() {
return OPEN_USER_INFO_URL;
}
public static String getOpenQrcodeUrl() {
return OPEN_QRCODE_URL;
}

public static String getOpenAccessTokenUrl() {
return OPEN_ACCESS_TOKEN_URL;
}
}
2.第二步
/***
* @Description: 用戶生成用戶能掃一掃的微信二維碼
* @Param: [accessPage]
* @return: cn.unicom.com.utils.JsonData
* @author: wangbs
* @create: 2019/2/1 8:52
*/
@GetMapping("login_url")
@ResponseBody
public JsonData loginUrl(@RequestParam(value = "access_page",required = true)String accessPage) throws UnsupportedEncodingException {
//獲取跳轉到咱們本身項目的重定向地址
String redirectUrl = weChatConfig.getOpenRedirectUrl();
String callbackUrl = URLEncoder.encode(redirectUrl,"GBK"); //進行編碼
String qrcodeUrl = String.format(weChatConfig.getOpenQrcodeUrl(), weChatConfig.getOpenAppid(), callbackUrl, accessPage);
return JsonData.buildSuccess(qrcodeUrl);
}
3.第三步
/***
* @Description: 咱們本身網站用於回調的藉口
* @Param: [code=>用戶的惟一標識, state=》咱們本身設定帶的參數(比較帶用戶當前掃碼的地址), response]
* @return: cn.unicom.com.utils.JsonData
* @author: wangbs
* @create: 2019/2/1 14:20
*/
@GetMapping("callback")
@ResponseBody
public JsonData callback(@RequestParam(value = "code",required = true) String code,
String state, HttpServletResponse response){
//保存用戶 微信一鍵登陸的(剩下的兩次交互寫在了service)
User user = userService.saveWeChatUser(code);
//判斷用戶是否成功登錄 不爲null 用戶登陸成功,作你該作的業務,爲null 用戶沒登陸。
if(user != null){
//生成jwt
String token = JwtUtils.geneJsonWebToken(user);
// state 當前用戶的頁面地址,須要拼接 http:// 這樣纔不會站內跳轉
response.sendRedirect(state+"?token="+token+"&head_img="+user.getHeadImg()+"&name="+URLEncoder.encode(user.getName(),"UTF-8"));
}
return null ;
}

a.service
@Override
public User saveWeChatUser(String code) {
//獲取和微信客戶端的第二次交互的url(記得帶上appid+appsecret+code)
    String accessTokenUrl = String.format(WeChatConfig.getOpenAccessTokenUrl(),weChatConfig.getOpenAppid(),weChatConfig.getOpenAppsecret(),code);
   //和微信客戶端的第二次交互,獲取appid和access_token
Map<String, Object> baseMap = HttpUtils.doGet(accessTokenUrl);
//access_token openid
if(baseMap == null || baseMap.isEmpty()){ return null; }
String accessToken = (String)baseMap.get("access_token");
String openId = (String) baseMap.get("openid");
//在這裏用戶已經登錄了,咱們首先拿到用戶的惟一標識openid 去咱們的user表中查,該用戶是否存在
User userByOptionId = userMapper.findUserByOptionId(openId);
//用戶信息在咱們數據庫有了 直接放心
if (userByOptionId!=null){
return userByOptionId;
}
//用戶第一次經過掃一掃登陸咱們系統
//獲取和微信客戶端的第三次交互的鏈接
String userInfoUrl = String.format(WeChatConfig.getOpenUserInfoUrl(),accessToken,openId);
  //經過第三次訪問微信鏈接 得到 用戶信息
    Map<String ,Object> baseUserMap =  HttpUtils.doGet(userInfoUrl);
if(baseUserMap == null || baseUserMap.isEmpty()){ return null; }
String nickname = (String)baseUserMap.get("nickname");
Double sexTemp = (Double) baseUserMap.get("sex");
int sex = sexTemp.intValue();
String province = (String)baseUserMap.get("province");
String city = (String)baseUserMap.get("city");
String country = (String)baseUserMap.get("country");
String headimgurl = (String)baseUserMap.get("headimgurl");
StringBuilder sb = new StringBuilder(country).append("||").append(province).append("||").append(city);
String finalAddress = sb.toString();
try {
//解決亂碼
nickname = new String(nickname.getBytes("ISO-8859-1"), "UTF-8");
finalAddress = new String(finalAddress.getBytes("ISO-8859-1"), "UTF-8");

} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
  //封裝用戶信息保存用戶
User user=new User();
user.setOpenid(openId);
user.setName(nickname);
user.setSex(sex);
user.setHeadImg(headimgurl);
user.setCreateTime(new Date());
user.setCity(finalAddress);
userMapper.saveUser(user);
return user;
}
複製下方date中的鏈接去瀏覽器(就是二維碼)

 

 用戶掃一掃就登錄了。工具


//上面代碼親自測試的 有效 缺失點實體類啥的本身補上。 還有上面提到的域名映射的問題測試的話能夠用(ngrock) http://ngrok.ciqiuwl.cn/ 這個工具可以實現本地ip和域名的映射。別人就能經過外網訪問你的域名從而能訪問你的ip了。這軟件只能本身練習用,不能幹非法的事。
相關文章
相關標籤/搜索