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


1.注冊微信開放平台https://open.weixin.qq.com,一定要清楚微信開放平台和微信公眾平台是分別獨立的,不能共用。

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 (是應用接口使用密鑰) 還有就是指定我們注冊時,

對應的域名,方便我們以后進行域名映射跳轉。 第4不是微信官方文檔我們的會和微信交互3次,這三個連接都是從文檔上拿的記得好好看。

整體流程就是:

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

==貼代碼

1.第一步

 

**
*@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了。這軟件只能自己練習用,不能干非法的事。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM