微信第三方登入——JAVA後臺
阿新 • • 發佈:2019-02-11
小編在此說一聲,建議去看一下微信官方提供的流程圖,以及其他的之後再看下面的。小編在此就不提供賬號申請,那些準備工作了,直接上程式碼。
微信登入流程:
第一步:APP或者網頁端,通過賬號密碼獲取到微信返回的一個code碼。code碼,有效期為10分鐘,10分鐘不使用則自動失效,有效次數為一次,每一次的code碼都是不同的。[前端或者移動端的操作]
第二步:將code碼傳給後臺登入的介面(紅色部分為需要程式碼)
public String appLogin(){ //從header頭部裡面取出裝置型別,裝置編號,以及登入方式 String loginMode = request.getHeader("channel"); String modeType = request.getHeader("app-idfa"); String modeCode = request.getHeader("device"); Map<String, Object> headerMap = new HashMap<String, Object>(); headerMap.put("loginMode", loginMode); headerMap.put("modeType", modeType); headerMap.put("modeCode", modeCode); //載入配置檔案 Map<String, Object> maps = LoadingAuthUtil.loading(); String secret = (String) maps.get("secret"); //獲取傳過來的code String o = request.getParameter("object"); Map<String, Object> oMap = (Map<String, Object>) JSON.parse(o); String code = (String) oMap.get("code"); //調取微信的認證授權後的token Map<String, Object> map=new HashMap<String, Object>(); Map<String, Object> returnMap = jwtLoginService.getAccessToken(code,headerMap);
if(StringUtils.isEmpty(returnMap.get("accessToken")+"")||StringUtils.isEmpty(returnMap.get("isFirstLogin")+"")){ return returnJson(map, "0", ""); } String accessToken = (String) returnMap.get("accessToken"); String isFirstLogin = (String) returnMap.get("isFirstLogin"); //將openid取出來 String openid = JwtTokenUtil.getOpenidStringFromToken(accessToken, secret); //根據open_id,然後調取資料庫獲取資訊 User user = userService.getInfoByOpenId(openid); //將加密字串與使用者資訊一起傳給APP端 //放進map,轉成JSON map.put("authorization", accessToken); map.put("userCode", user.getUser_code()); map.put("nickName",user.getNick_name()); map.put("gender", user.getGender()); map.put("userIcon", user.getUser_image()); map.put("user_nationality", user.getUser_nationality()); map.put("province", user.getProvince()); map.put("city", user.getCity());; map.put("isFirstLogin",isFirstLogin); map.put("invitateCode", user.getInvitate_code()); map.put("shareIcon", user.getShareIcon()); map.put("invitatedCode", user.getInvitated_code()); map.put("tel", user.getUser_tel()); return returnJson(map, "0", ""); }//獲取傳過來的code String o = request.getParameter("object"); Map<String, Object> oMap = (Map<String, Object>) JSON.parse(o); String code = (String) oMap.get("code"); //調取微信的認證授權後的token Map<String, Object> map=new HashMap<String, Object>(); Map<String, Object> returnMap = jwtLoginService.getAccessToken(code,headerMap);if(StringUtils.isEmpty(returnMap.get("accessToken")+"")||StringUtils.isEmpty(returnMap.get("isFirstLogin")+"")){ return returnJson(map, "0", ""); } String accessToken = (String) returnMap.get("accessToken"); String isFirstLogin = (String) returnMap.get("isFirstLogin"); //將openid取出來 String openid = JwtTokenUtil.getOpenidStringFromToken(accessToken, secret); //根據open_id,然後調取資料庫獲取資訊 User user = userService.getInfoByOpenId(openid); //將加密字串與使用者資訊一起傳給APP端 //放進map,轉成JSON map.put("authorization", accessToken); map.put("userCode", user.getUser_code()); map.put("nickName",user.getNick_name()); map.put("gender", user.getGender()); map.put("userIcon", user.getUser_image()); map.put("user_nationality", user.getUser_nationality()); map.put("province", user.getProvince()); map.put("city", user.getCity());; map.put("isFirstLogin",isFirstLogin); map.put("invitateCode", user.getInvitate_code()); map.put("shareIcon", user.getShareIcon()); map.put("invitatedCode", user.getInvitated_code()); map.put("tel", user.getUser_tel()); return returnJson(map, "0", ""); }
第三步:通過code調取微信的伺服器獲取access_token
/**
* description: 根據認證碼調取微信平臺獲取資訊
* @param code 認證碼
* @return 返回json資料
*/
public Map<String, Object> getAccessToken(String code,Map<String, Object> m) {
logger.info("code:"+code);
Map<String, Object> returnMap =new HashMap<String, Object>();
//----------------------- 載入配置檔案 ----------------------
Map<String, Object> maps =LoadingAuthUtil.loading();
String tokenUrl = (String) maps.get("tokenUrl");
String appid = (String) maps.get("appid");
String secret = (String) maps.get("secret");
//--------------------------呼叫微信後臺伺服器----------------------------
String url= tokenUrl+"appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code";
URI uri = URI.create(url);
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(uri);
HttpResponse response;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
StringBuilder sb = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
sb.append(temp);
}
if(sb.toString().contains("errcode")){
logger.info(""+sb.toString());
returnMap.put("isFirstLogin", null);
returnMap.put("accessToken", null);
}else{
JSONObject object = new JSONObject().fromObject(sb.toString().trim());
logger.info("wechat info:"+object);
//獲取所需要的資訊
String accessToken = object.getString("access_token");
String openID = object.getString("openid");
String refreshToken = object.getString("refresh_token");
long expires_in = object.getLong("expires_in"); //獲取騰訊過期時間
//token過期時間
Date expires_time=new Date(System.currentTimeMillis()+expires_in*1000);
String unionid = object.getString("unionid");
String scope = object.getString("scope");
//根據open_id(執行資料的新增和修改)
String isFirstLogin = getUserInfo(accessToken,openID);
JwtToken jwtToken = new JwtToken(openID,unionid, expires_time, accessToken, refreshToken, scope);
//根據open_id,然後調取資料庫獲取資訊
User user = userService.getInfoByOpenId(openID);
//將使用者id取出來
Long userId = user.getId();
//將使用者id設定進JwtToken物件裡面
jwtToken.setUserid(userId+"");
//將token加密
String authorization = JwtTokenUtil.generateAccessToken(jwtToken);
//將token存在redis裡面
redisUtil.set(RedisPropertyUtil.RedisLoginTokenKey+userId, authorization);
//新增登入流水
String login_mode = (String) m.get("loginMode");
String mode_type = (String) m.get("modeType");
String mode_code = (String) m.get("modeCode");
Login lt = new Login();
lt.setUser_id(userId+"");
lt.setAuthorization(authorization);
lt.setLogin_mode(login_mode);
lt.setAccess_token(accessToken);
lt.setRefresh_token(refreshToken);
lt.setMode_type(mode_type);
lt.setMode_code(mode_code);
loginService.insert(lt);
returnMap.put("isFirstLogin", isFirstLogin);
returnMap.put("accessToken", authorization);
}
return returnMap;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
第四步:根據access_token獲取使用者資訊
/**
* @description: 根據accessToken和open_id 獲取使用者資訊,執行資料庫判斷
*/
private String getUserInfo(String accessToken,String openID){
//----------------------- 載入配置檔案 ----------------------
Map<String, Object> maps =LoadingAuthUtil.loading();
String userInfoUrl = (String) maps.get("userInfoUrl");
String uri = userInfoUrl+"access_token=" + accessToken + "&openid=" + openID;
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(URI.create(uri));
String isFirstLogin = "0"; //預設不是第一次登入
try {
HttpResponse response = client.execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
StringBuilder builder = new StringBuilder();
for (String temp = reader.readLine(); temp != null; temp = reader.readLine()) {
builder.append(temp);
}
JSONObject object = new JSONObject().fromObject(builder.toString().trim());
//獲取微信返回的使用者基本資訊
String nickName =object.getString("nickname");
String sex=object.getString("sex");
String province=object.getString("province");
String city=object.getString("city");
String country=object.getString("country");
String headimgurl=object.getString("headimgurl");
String unionid=object.getString("unionid");
logger.info("wechat info: "+nickName+"---"+sex+"---"+province+"---"+city+"---"+country+"---"+headimgurl+"---"+unionid+"---");
//例項化一個使用者
User user=new User();
user.setNick_name(nickName);
user.setOpenid(openID);
user.setUnionid(unionid);
user.setUser_icon(headimgurl);
user.setGender(sex);
user.setUser_nationality(country);
user.setProvince(province);
user.setCity(city);
//判斷是否是第一次登入
int count = userService.judgeUserByOpenId(openID);
logger.info("count:"+count);
if (count == 0) {//查詢資料庫是否有open_id
logger.info("first login");
//第一次登入,則生成一個唯一的邀請碼
String invitateCode = InvitateCodeUtil.createCode();
int v = userService.judgeCodeByCode(invitateCode);
boolean flag= true;
while(flag){
if(v>0){//說明資料庫中已經存在此邀請碼,則需要重新生成再繼續判斷
invitateCode = InvitateCodeUtil.createCode();
v = userService.judgeCodeByCode(invitateCode);
}else{
flag = false;
}
}
//首次登入,根據邀請碼自動生成一張圖片
if(invitateCode != null){
//載入配置檔案
Map<String, Object> shareMap = LoadingShareUtil.loading();
String backgroundUrl = (String) shareMap.get("backgroundUrl");
String aboveUrl = (String) shareMap.get("aboveUrl");
String compoundUrl = (String) shareMap.get("compoundUrl");
String compoundName = (String) shareMap.get("compoundName");
String text = invitateCode;
String finalUrl = (String) shareMap.get("finalUrl");
String finalName = "share_"+invitateCode+"_"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".png";
String str[]={ "386", "984" };
ImageUtil.crearePicture(backgroundUrl, aboveUrl, compoundUrl, compoundName, text, finalUrl, finalName,str);
String cosIconPath = TxFileUpload.upload(finalUrl+finalName, finalName, "share");
user.setShareIcon(cosIconPath); //設定地址
}
//設定使用者型別(預設是普通會員)
user.setUser_type("4");
//設定邀請碼
user.setInvitate_code(invitateCode);
//如果是第一次登入則新增進資料庫
userService.insert(user);
//根據openid 找到剛剛新增的user
User t = userService.getInfoByOpenId(openID);
//生成userCode
String userCode = UserCodeUtil.createUserCode(t.getId()+"");
//修改userCode編碼
t.setUser_code(userCode);
//修改資訊
userService.update(t);
//首次登陸要送獎勵
String coin = sysConfigService.getValue("SYSTEM", "REWARD", "LOGIN_FRIST");
Map<String, Object> rewardMap = RewardSplitUtil.SplitReward(coin);
String rewardCoin = (String) rewardMap.get("rewardCoin");
String exerciseCoin = (String) rewardMap.get("exerciseCoin");
try {
//執行新增遊戲幣的服務
Map<String, Object> accountMap =new HashMap<String, Object>();
accountMap.put("userId", t.getId());
//預設充值賬戶
accountMap.put("accountType", 1);
accountMap.put("balance", rewardCoin);
userAccountService.addBalance(accountMap);
//執行新增練習賬戶的服務
Map<String, Object> accountMap1 =new HashMap<String, Object>();
accountMap1.put("userId", t.getId());
//預設充值賬戶
accountMap1.put("accountType", 2);
accountMap1.put("balance", exerciseCoin);
userAccountService.addBalance(accountMap1);
} catch (Exception e) {
e.printStackTrace();
}
isFirstLogin="1";
}else{//如果不是第一次登入,則執行修改的操作,更新資料庫
//根據openId獲取userId
User t = userService.getInfoByOpenId(openID);
user.setId(t.getId());
logger.info(t.getId()+"no first login");
userService.update(user);
}
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return isFirstLogin;
}
小編在此就不細細說明了,有什麼問題註釋應該都寫了,還有要問題的,可以聯絡QQ985548426.小編長期線上。