微信登陸-PC端

JAVA 登陸這個功能我是隻請求了微信的登陸,token、登陸時長等設置我仍是使用了本身項目來控制的css

微信登陸真的很坑,建議理解透了再動手開發,下面核心的地方我標註起來了前端

向APPID之類的東西,建議添加到配置裏面,有不懂的能夠在下面留言java

小程序登陸能夠看一下個人另外一篇文章,相對來講更簡單一點 : 微信登陸-小程序版本json

話很少說,直接貼源碼,複製便可用,wink~小程序

private static Logger log = LoggerFactory.getLogger(XXX.class);

//調用微信接口時,增長的css樣式,能夠不用加,文檔上有
private String href = "https://www.oschina.net/login-qrcode.css";
//回調本身項目的前端地址
private String callBackHref = "https://www.oschina.net/";

/**
 * @Author : Yanqiang
 * @Date : 2019/3/7
 * @Param : [request]
 * @return : java.util.Map<java.lang.String,java.lang.Object>
 * @Description : 返回微信二維碼,可供掃描登陸
 *
 *  總體請求流程:
 *        登陸頁面點擊微信登陸 ——> 請求後端的qrconnect()接口 ——> 後端請求:https://open.weixin.qq.com/connect/qrconnect 而且傳遞用戶掃碼後微信回調項目的地址
 *        ——> 微信本身去判斷用戶有沒有掃碼(不須要本身寫) ——> (已掃碼)微信回調你請求時傳遞的接口
 *  PS:
 *      如下爲排坑!!!
 *
 *      微信公衆平臺 and 微信開放平臺 是不同的東西
 *
 *      微信登陸分爲 1·PC端, 2·APP, 3·小程序, 4·公衆號 ....
 *      以上調用的地址是不一樣的!!! PC端 在這個地址註冊 https://open.weixin.qq.com/ 點網站應用開發,好像是註冊一個三百多塊錢,準備好money
 *      這個地址是公衆號的開發!!!https://mp.weixin.qq.com/wiki 千萬不要看這個去開發PC
 *      不一樣應用之間APPID和Secret都不同(即便多個小程序或多個PC也是不一樣的),一個應用一個,千萬不要用錯了,
 */
@RequestMapping(value = "qrconnect", method = RequestMethod.GET)
public BaseResult qrconnect(HttpServletRequest request, HttpServletResponse response){
    BaseResult baseResult = new BaseResult();
    //微信二維碼的接口
    String wxLoginurl = "https://open.weixin.qq.com/connect/qrconnect?" +
            "appid={APPID}&redirect_uri={REUTL}&response_type=code&scope=snsapi_login&state={STATE}&href={HREF}#wechat_redirect";
    //拼接組裝掃碼登陸url
    wxLoginurl = wxLoginurl.replace("{APPID}", "微信發放的APPID")
            .replace("{REUTL}","微信回調你本身項目的接口路徑")//這裏就是指向下面的getUserInfo()接口
            .replace("{STATE}","隨意填寫的值,我是生成了一個隨機數,也能夠不變")
            .replace("{HREF}",href);//調用微信接口時,增長的css樣式,能夠不用加,文檔上有
    //發送請求
    String result = response.encodeURL(wxLoginurl);
    log.info("==掃碼result :"+result);
    // response.sendRedirect(result);
    //這裏能夠直接重定向到你的項目的前端地址,
    // 個人項目本身把二維碼鑲嵌在本身的網頁中,
    // 沒有直接跳到微信的二維碼網頁,因此返回地址就能夠了,前端作處理
    baseResult.setData(result);
    return baseResult;
}

/**
 * @Author : Yanqiang
 * @Date : 2019/3/7
 * @Param : [map, request, response]
 * @return : java.lang.String
 * @Description : 微信獲取用戶信息,用戶掃碼後微信調用此接口
 *  請求流程:
 *          獲取code ——> 用code獲取AccessToken ——> 用AccessToken獲取userinfo
 *
 *  1·獲取微信調用時傳遞的參數code: String code = request.getParameter("code")
 *  2·經過Appid,Secret,code 去獲取AccessToken;接口:https://api.weixin.qq.com/sns/oauth2/access_token
 *  3·經過AccessToken去請求用戶信息;接口:https://api.weixin.qq.com/sns/userinfo
 *  4·unionid:
 *          4.1 只有關聯了小程序纔有這個,沒關聯的只有openid
 *          4.2 多個應用同一用戶的unionid 相同且惟一(應該相似用戶在微信的惟一ID)
 *  5·openid:
 *          5.1 不一樣應用之間同一用戶的openid是不一樣的(即便大家公司多個小程序也是不一樣的)
 *          5.2 相同應用中同一用戶openid是相同的
 *  6·強烈推薦剛開始作項目就關聯起來,使用unionid作用戶二級ID,即便不使用unionid,也要記錄起來,否則後期是個大問題
 */
@RequestMapping(value = "getUserInfo", method = RequestMethod.GET)
public void getUserInfo(HttpServletRequest request, HttpServletResponse response) throws IOException {
    request.setCharacterEncoding("utf-8");
    response.setCharacterEncoding("utf-8");
    //從微信傳遞的參數裏獲取code
    String code = request.getParameter("code");
    // 經過code獲取WeixinOauth2Token 再獲取 access_token
    WeixinOauth2Token oauth2Token = WeiXinUtil.getOauth2AccessToken("微信發放的APPID", "微信發放的Secret", code);
    log.info("===========code = "+code+"===========");
    String accessToken=oauth2Token.getAccessToken();
    log.info("===========accessToken = "+accessToken+"===========");
    String openId=oauth2Token.getOpenId();
    log.info("===========openId = "+openId+"===========");
    //獲取到用戶的基本信息
    JSONObject snsUserInfo = WeiXinUtil.getSNSUserInfo(accessToken, openId);
    log.info("===========snsUserInfo = "+snsUserInfo.toString()+"===========");
    if(snsUserInfo!=null){
        //這裏能夠直接拿到用戶信息了,就能夠你的業務處理了
        String headimgurl = (String) snsUserInfo.get("headimgurl");
        String nickname = (String) snsUserInfo.get("nickname");
        String language = (String) snsUserInfo.get("language");
        String province = (String) snsUserInfo.get("province");
        String country = (String) snsUserInfo.get("country");
        String unionId = (String) snsUserInfo.get("unionid");
        String openid = (String) snsUserInfo.get("openid");
        int sex = (Integer) snsUserInfo.get("sex");
        //重定向到你的項目的前端地址
        response.sendRedirect(callBackHref+"?code=1");
    }else{
        //獲取不到用戶 登陸失敗 重定向到你的項目的前端地址,而且傳遞一個狀態值
        response.sendRedirect(callBackHref+"?code=0");
    }
}

如下爲使用到的工具類後端

WeiXinUtilapi

public class WeiXinUtil {

    private static Logger log = LoggerFactory.getLogger(WeiXinUtil.class);
    //把 appid和appsecret改了就行
    public final static String AccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    public final static String userinfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    

    /**
     * @Author : Yanqiang
     * @Date : 2019/3/7
     * @Param : [appId, appSecret, code]
     * @return : com.mjt.passport.util.WeiXinUtils.WeixinOauth2Token
     * @Description : 網頁受權認證
     */
    public static WeixinOauth2Token getOauth2AccessToken(String appId,String appSecret,String code) {

        String  requestUrl=AccessTokenUrl.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
        //發送請求獲取網頁受權憑證,這個httpsRequest就不貼出來了,就是發送http請求,網上一大把,本身寫也很快
        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, EnumMethod.GET.name(), null);
        WeixinOauth2Token wxot=new WeixinOauth2Token();
        wxot.setAccessToken(jsonObject.getString("access_token"));
        wxot.setExpiresIn(jsonObject.getInt("expires_in"));
        wxot.setRefreshToken(jsonObject.getString("refresh_token"));
        wxot.setOpenId(jsonObject.getString("openid"));
        wxot.setScope(jsonObject.getString("scope"));
        return wxot;
    }

    /**
     * @Author : Yanqiang
     * @Date : 2019/3/7
     * @Param : [accessToken, openId]
     * @return : com.mjt.passport.util.WeiXinUtils.SNSUserInfo
     * @Description : 獲取用戶的基本信息 打印log日誌 便於查找問題
     */
    public static JSONObject getSNSUserInfo(String accessToken,String openId) {
        String requestUrl=userinfoUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        log.info("===========requestUrl = "+requestUrl+"===========");
        //經過網頁受權獲取用戶信息
        JSONObject jsonObject=CommonUtil.httpsRequest(requestUrl, EnumMethod.GET.name(), null);
        log.info("===========jsonObject = "+jsonObject+"===========");
        return jsonObject;
    }

}

WeixinOauth2Token微信

public class WeixinOauth2Token {
   
   //網頁受權接口調用憑證
   private  String accessToken;
   
   //憑證有效時長
   private int expiresIn;
   
   //用於刷新憑證
   private String refreshToken;
   
   //用戶標識
   private String openId;
   
   //用戶受權做用域(當scope=snsapi_base時,不彈出受權頁面,直接跳轉 只能獲取到openId,當scope=snsapi=userinfo時彈出受權頁面,獲取用戶信息)
   private String scope;

   public String getAccessToken() {
      return accessToken;
   }

   public void setAccessToken(String accessToken) {
      this.accessToken = accessToken;
   }

   public int getExpiresIn() {
      return expiresIn;
   }

   public void setExpiresIn(int expiresIn) {
      this.expiresIn = expiresIn;
   }

   public String getRefreshToken() {
      return refreshToken;
   }

   public void setRefreshToken(String refreshToken) {
      this.refreshToken = refreshToken;
   }

   public String getOpenId() {
      return openId;
   }

   public void setOpenId(String openId) {
      this.openId = openId;
   }

   public String getScope() {
      return scope;
   }

   public void setScope(String scope) {
      this.scope = scope;
   }
}
相關文章
相關標籤/搜索