600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > [JAVA实现]微信公众号网页授权登录 java开发面试笔试题

[JAVA实现]微信公众号网页授权登录 java开发面试笔试题

时间:2021-11-05 19:00:28

相关推荐

[JAVA实现]微信公众号网页授权登录 java开发面试笔试题

我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家。

扫描二维码或搜索下图红色VX号,加VX好友,拉你进【程序员面试学习交流群】免费领取。也欢迎各位一起在群里探讨技术。

推荐文章:Java 面试知识点解析;Mysql优化技巧(数据库设计、命名规范、索引优化

网上搜资料时,网友都说官方文档太垃圾了不易看懂,如何如何的。现在个人整理了一个通俗易懂易上手的,希望可以帮助到刚接触微信接口的你。

请看流程图!看懂图,就懂了一半了:

其实整体流程大体只需三步:用户点击登录按钮(其实就相当于一个链接) ---》 用户点击授权登录 ----》 实现获取用户信息代码。

然后获取用户信息代码只需三步:获取code ----》 通过code获取access_token和openId ---》 通过access_token和openId获取用户信息(包含union)。

以上便是整体套路,当然官网上也有,但具体如何实现呢?

不着急,咱们一步一步来!

第一步:微信登录按钮

它其实就是一个连接,不过想得到这个链接,有一点点麻烦。

1、设置。 微信公众平台---》接口权限---》网页授权---》修改 ---》设置网页授权域名(域名,不含http://),其实就是微信调你的java方法的项目路径或项目域名,如:/pp ---》点击设置后弹出页面(大致意思,将MP_verify_31qRIDcjN8ZD1lVJ.txt放在你项目路径下面,如:/pp/MP_verify_31qRIDcjN8ZD1lVJ.txt 能访问到) ---》点击确认,授权回调页面域名设置成功!

2、拼链接。 https://open./connect/oauth2/authorize?appid=xxx公众号IDxxxxx & redirect_uri = 授权回调页面域名/你的action(即微信授权后跳向的地址)

& response_type=code(固定的) & scope = snsapi_userinfo(或者snsapi_base默认授权) & state=STATE#wechat_redirect

如:https://open./connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

这个链接中参数的具体含义,官方解释如下:

第二步:授权确认登录

这一步最简单,第一步登录链接拼好后,在手机微信中打开,微信便会跳转到确认授权页面,点击确认授权即可。(这一步,不用开发者做处理!)

第三步:获取用户信息 (重点)

这一步便是真正的代码实现的地方。开篇便讲了,它只需三步:获取code ----》 通过code获取access_token和openId ---》 通过access_token和openId获取用户信息。

First: 获取code

Second: 获取网页授权access_token和openId

Third:通过access_token和openId获取用户信息。

关于union机制的细节:如果开发者需要公众号微信登录和APP微信登录共用一个微信ID,那个就需要union机制了。其实很简单,只需在微信开放平台(open.)绑定公众号,获取用户信息时就会返回union字段。

具体代码实现为:实体 ---- 方法 --- 工具

实体Oauth2Token:

1 package com.wfcm.wxUitls; 2 3 /** 4 * 类名: WeixinOauth2Token </br> 5 * 描述: 网页授权信息 </br> 6 * 创建时间: -11-27 </br> 7 * 发布版本:V1.0 </br> 8 */ 9 public class Oauth2Token {10// 网页授权接口调用凭证11private String accessToken;12// 凭证有效时长13private int expiresIn;14// 用于刷新凭证15private String refreshToken;16// 用户标识17private String openId;18// 用户授权作用域19private String scope;20 21public String getAccessToken() {22 return accessToken;23}24 25public void setAccessToken(String accessToken) {26 this.accessToken = accessToken;27}28 29public int getExpiresIn() {30 return expiresIn;31}32 33public void setExpiresIn(int expiresIn) {34 this.expiresIn = expiresIn;35}36 37public String getRefreshToken() {38 return refreshToken;39}40 41public void setRefreshToken(String refreshToken) {42 this.refreshToken = refreshToken;43}44 45public String getOpenId() {46 return openId;47}48 49public void setOpenId(String openId) {50 this.openId = openId;51}52 53public String getScope() {54 return scope;55}56 57public void setScope(String scope) {58 this.scope = scope;59}60 }

View Code

实体SNSUserInfo:

1 package com.wfcm.wxUitls; 2 3 import java.util.List; 4 5 /** 6 * 类名: SNSUserInfo </br> 7 * 描述: 通过网页授权获取的用户信息 </br> 8 * 开发人员: wzf </br> 9 * 创建时间: -11-27 </br> 10 * 发布版本:V1.0 </br> 11 */ 12 public class SNSUserInfo { 13// 用户标识 14private String openId; 15// 用户昵称 16private String nickname; 17// 性别(1是男性,2是女性,0是未知) 18private int sex; 19// 国家 20private String country; 21// 省份 22private String province; 23// 城市 24private String city; 25// 用户头像链接 26private String headImgUrl; 27// 用户特权信息 28private List<String> privilegeList; 2930private String unionid; 31 32public String getUnionid() { 33 return unionid; 34} 35 36public void setUnionid(String unionid) { 37 this.unionid = unionid; 38} 39 40public String getOpenId() { 41 return openId; 42} 43 44public void setOpenId(String openId) { 45 this.openId = openId; 46} 47 48public String getNickname() { 49 return nickname; 50} 51 52public void setNickname(String nickname) { 53 this.nickname = nickname; 54} 55 56public int getSex() { 57 return sex; 58} 59 60public void setSex(int sex) { 61 this.sex = sex; 62} 63 64public String getCountry() { 65 return country; 66} 67 68public void setCountry(String country) { 69 this.country = country; 70} 71 72public String getProvince() { 73 return province; 74} 75 76public void setProvince(String province) { 77 this.province = province; 78} 79 80public String getCity() { 81 return city; 82} 83 84public void setCity(String city) { 85 this.city = city; 86} 87 88public String getHeadImgUrl() { 89 return headImgUrl; 90} 91 92public void setHeadImgUrl(String headImgUrl) { 93 this.headImgUrl = headImgUrl; 94} 95 96public List<String> getPrivilegeList() { 97 return privilegeList; 98} 99 100public void setPrivilegeList(List<String> privilegeList) {101 this.privilegeList = privilegeList;102}103 }

View Code

方法WxController(其中authorize() 方法就是请求第一步获取的链接):

1 package com.wfcm.controller; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.UnsupportedEncodingException; 7 import .URL; 8 import .URLConnection; 9 import .URLEncoder; 10 import java.security.MessageDigest; 11 import java.security.NoSuchAlgorithmException; 12 import java.util.ArrayList; 13 import java.util.Formatter; 14 import java.util.HashMap; 15 import java.util.List; 16 import java.util.Map; 17 import java.util.UUID; 18 19 import javax.servlet.http.HttpServletRequest; 20 import javax.servlet.http.HttpServletResponse; 21 22 import org.apache.http.client.utils.URLEncodedUtils; 23 import org.json.JSONObject; 24 import org.slf4j.Logger; 25 import org.slf4j.LoggerFactory; 26 import org.springframework.beans.factory.annotation.Autowired; 27 import org.springframework.stereotype.Controller; 28 import org.springframework.web.bind.annotation.RequestMapping; 29 import org.springframework.web.bind.annotation.ResponseBody; 30 31 import com.alibaba.fastjson.JSON; 32 import com.alibaba.fastjson.JSONArray; 33 import com.alibaba.fastjson.util.IOUtils; 34 import com.wfcm.annotation.IgnoreSign; 35 import com.wfcm.annotation.IgnoreToken; 36 import com.wfcm.entity.WfMemberEntity; 37 import com.wfcm.service.WfMemberService; 38 import com.wfcm.service.WfMemberSessionService; 39 import com.wfcm.utils.FastJSONUtils; 40 import com.Util; 41 import com.wfcm.utils.R; 42 import com.wfcm.wxUitls.AccessToken; 43 import com.wfcm.wxUitls.JsapiTicket; 44 import com.wfcm.wxUitls.Oauth2Token; 45 import com.wfcm.wxUitls.SNSUserInfo; 46 47 @Controller 48 @RequestMapping("/wx") 49 @ResponseBody 50 public class WxController { 51 52private static Logger log = LoggerFactory.getLogger(WxController.class); 53 5455/** 56* 向指定URL发送GET方法的请求 57* 58* @param url 59* 发送请求的URL 60* @param param 61* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 62* @return URL 所代表远程资源的响应结果 63* 64* 用户同意授权,获取code 65*/ 66@RequestMapping("/authorize") 67@ResponseBody 68@IgnoreToken 69public static R authorize() { 70 String appid = "wxbb000000000e"; 71 //String uri ="/wx/weixinLogin"; 72 String uri = urlEncodeUTF8("/api/wx/weixinLogin"); 73 String result = ""; 74 BufferedReader in = null; 75 try { 76 String urlNameString = "https://open./connect/oauth2/authorize?appid="+appid+"&redirect_uri="+uri+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"; 77 78 URL realUrl = new URL(urlNameString); 79 // 打开和URL之间的连接 80 URLConnection connection = realUrl.openConnection(); 81 // 设置通用的请求属性 82 connection.setRequestProperty("accept", "*/*"); 83 connection.setRequestProperty("connection", "Keep-Alive"); 84 connection.setRequestProperty("user-agent", 85 "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 86 // 建立实际的连接 87 connection.connect(); 88 // 获取所有响应头字段 89 Map<String, List<String>> map = connection.getHeaderFields(); 90 // 遍历所有的响应头字段 91 for (String key : map.keySet()) { 92 System.out.println(key + "--->" + map.get(key)); 93 } 94 // 定义 BufferedReader输入流来读取URL的响应 95 in = new BufferedReader(new InputStreamReader( 96 connection.getInputStream())); 97 String line =null; 98 while ((line = in.readLine()) != null) { 99 result += line;100 }101 /* com.alibaba.fastjson.JSONObject jsonObj= FastJSONUtils.getJSONObject(result); 102 String access_token = jsonObj.getString("access_token");103 long expires_in = Long.valueOf(jsonObj.getString("expires_in"));104 */105 } catch (Exception e) {106 System.out.println("发送GET请求出现异常!" + e);107 e.printStackTrace();108 }109 // 使用finally块来关闭输入流110 finally {111 try {112 if (in != null) {113 in.close();114 }115 } catch (Exception e2) {116 e2.printStackTrace();117 }118 }119 return R.ok(result);120} 121122@RequestMapping("/weixinLogin")123@ResponseBody124@IgnoreToken125@IgnoreSign126public void weixinLogin(HttpServletRequest request,HttpServletResponse response) throws Exception { 127 // 用户同意授权后,能获取到code128 Map<String, String[]> params = request.getParameterMap();//针对get获取get参数 129 String[] codes = params.get("code");//拿到code的值 130 String code = codes[0];//code 131 //String[] states = params.get("state");132 //String state = states[0];//state 133 134 System.out.println("****************code:"+code);135 // 用户同意授权136 if (!"authdeny".equals(code)) {137 // 获取网页授权access_token138 Oauth2Token oauth2Token = getOauth2AccessToken("wxb0000000000e", "4c22222233333335555a9", code);139 System.out.println("***********************************oauth2Token信息:"+oauth2Token.toString());140 // 网页授权接口访问凭证141 String accessToken = oauth2Token.getAccessToken();142 // 用户标识143 String openId = oauth2Token.getOpenId();144 // 获取用户信息145 SNSUserInfo snsUserInfo = getSNSUserInfo(accessToken, openId);146 System.out.println("***********************************用户信息unionId:"+snsUserInfo.getUnionid()+"***:"+snsUserInfo.getNickname());147 // 设置要传递的参数148 149 //具体业务start150 151 //具体业务end152 153 String url = "/#/biddd?from=login&tokenId="+snsUserInfo.getUnionid();154 155 response.sendRedirect(url); 156 return ;157 }158} 159 160161/**162* 获取网页授权凭证163* 164* @param appId 公众账号的唯一标识165* @param appSecret 公众账号的密钥166* @param code167* @return WeixinAouth2Token168*/169public static Oauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {170 Oauth2Token wat = null;171 // 拼接请求地址172 String requestUrl = "https://api./sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";173 requestUrl = requestUrl.replace("APPID", appId);174 requestUrl = requestUrl.replace("SECRET", appSecret);175 requestUrl = requestUrl.replace("CODE", code);176 // 获取网页授权凭证177 com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(NetUtil.get(requestUrl));178 if (null != jsonObject) {179 try {180 wat = new Oauth2Token();181 wat.setAccessToken(jsonObject.getString("access_token"));182 wat.setExpiresIn(jsonObject.getInteger("expires_in"));183 wat.setRefreshToken(jsonObject.getString("refresh_token"));184 wat.setOpenId(jsonObject.getString("openid"));185 wat.setScope(jsonObject.getString("scope"));186 } catch (Exception e) {187 wat = null;188 int errorCode = jsonObject.getInteger("errcode");189 String errorMsg = jsonObject.getString("errmsg");190 log.error("获取网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);191 }192 }193 return wat;194}195196/**197* 通过网页授权获取用户信息198* 199* @param accessToken 网页授权接口调用凭证200* @param openId 用户标识201* @return SNSUserInfo202*/203public static SNSUserInfo getSNSUserInfo(String accessToken, String openId) {204 SNSUserInfo snsUserInfo = null;205 // 拼接请求地址206 String requestUrl = "https://api./sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";207 requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);208 // 通过网页授权获取用户信息209 com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(NetUtil.get(requestUrl));210 211 if (null != jsonObject) {212 try {213 snsUserInfo = new SNSUserInfo();214 // 用户的标识215 snsUserInfo.setOpenId(jsonObject.getString("openid"));216 // 昵称217 snsUserInfo.setNickname(jsonObject.getString("nickname"));218 // 性别(1是男性,2是女性,0是未知)219 snsUserInfo.setSex(jsonObject.getInteger("sex"));220 // 用户所在国家221 snsUserInfo.setCountry(jsonObject.getString("country"));222 // 用户所在省份223 snsUserInfo.setProvince(jsonObject.getString("province"));224 // 用户所在城市225 snsUserInfo.setCity(jsonObject.getString("city"));226 // 用户头像227 snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));228 // 用户特权信息229 List<String> list = JSON.parseArray(jsonObject.getString("privilege"),String.class);230 snsUserInfo.setPrivilegeList(list);231 //与开放平台共用的唯一标识,只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。232 snsUserInfo.setUnionid(jsonObject.getString("unionid"));233 } catch (Exception e) {234 snsUserInfo = null;235 int errorCode = jsonObject.getInteger("errcode");236 String errorMsg = jsonObject.getString("errmsg");237 log.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);238 }239 }240 return snsUserInfo;241}242 243/**244* URL编码(utf-8)245* 246* @param source247* @return248*/249public static String urlEncodeUTF8(String source) {250 String result = source;251 try {252 result = .URLEncoder.encode(source, "utf-8");253 } catch (UnsupportedEncodingException e) {254 e.printStackTrace();255 }256 return result;257}258259private static String byteToHex(final byte[] hash) {260 Formatter formatter = new Formatter();261 for (byte b : hash)262 {263 formatter.format("%02x", b);264 }265 String result = formatter.toString();266 formatter.close();267 return result;268}269 270private static String create_nonce_str() {271 return UUID.randomUUID().toString();272}273 274private static String create_timestamp() {275 return Long.toString(System.currentTimeMillis() / 1000);276}277 }

View Code

工具NetUtil:

1 package com.wfcm.utils; 2 3 import java.io.BufferedInputStream; 4 import java.io.IOException; 5 import java.io.InputStreamReader; 6 import java.io.UnsupportedEncodingException; 7 import java.util.ArrayList; 8 import java.util.Collection; 9 import java.util.List;10 import java.util.Map;11 12 import mons.httpclient.NameValuePair;13 import org.apache.http.HttpEntity;14 import org.apache.http.HttpResponse;15 import org.apache.http.client.entity.UrlEncodedFormEntity;16 import org.apache.http.client.methods.HttpGet;17 import org.apache.http.client.methods.HttpPost;18 import org.apache.http.impl.client.CloseableHttpClient;19 import org.apache.http.impl.client.HttpClientBuilder;20 import org.apache.http.message.BasicNameValuePair;21 22 /**23 * Created by Song on /11/28.24 * 基于HttpClient提供网络访问工具25 */26 public final class NetUtil {27public static CloseableHttpClient httpClient = HttpClientBuilder.create().build();28 29/**30* get请求获取String类型数据31* @param url 请求链接32* @return33*/34public static String get(String url){35 StringBuffer sb = new StringBuffer();36 HttpGet httpGet = new HttpGet(url);37 try {38 HttpResponse response = httpClient.execute(httpGet); //139 40 HttpEntity entity = response.getEntity();41 InputStreamReader reader = new InputStreamReader(entity.getContent(),"utf-8");42 char [] charbufer;43 while (0<reader.read(charbufer=new char[10])){44 sb.append(charbufer);45 }46 }catch (IOException e){//147 e.printStackTrace();48 }finally {49 httpGet.releaseConnection();50 }51 return sb.toString();52}53 54/**55* post方式请求数据56* @param url 请求链接57* @param data post数据体58* @return59*/60@SuppressWarnings("unchecked")61public static String post(String url, Map<String,String> data){62 StringBuffer sb = new StringBuffer();63 HttpPost httpPost = new HttpPost(url);64 List<NameValuePair> valuePairs = new ArrayList<NameValuePair>();65 if(null != data) {66 for (String key : data.keySet()) {67 valuePairs.addAll((Collection<? extends NameValuePair>) new BasicNameValuePair(key, data.get(key)));68 }69 }70 try {71 httpPost.setEntity(new UrlEncodedFormEntity((List<? extends org.apache.http.NameValuePair>) valuePairs));72 HttpResponse response = httpClient.execute(httpPost);73 HttpEntity httpEntity = response.getEntity();74 BufferedInputStream bis = new BufferedInputStream(httpEntity.getContent());75 byte [] buffer;76 while (0<bis.read(buffer=new byte[128])){77 sb.append(new String(buffer,"utf-8"));78 }79 }catch (UnsupportedEncodingException e){//数据格式有误80 e.printStackTrace();81 }catch (IOException e){//请求出错82 e.printStackTrace();83 }finally {84 httpPost.releaseConnection();85 }86 return sb.toString();87}888990 }

View Code

R类:

package com.wfcm.utils;import java.util.HashMap;import java.util.Map;/** * 返回数据* * @author xlf* @email xlfbe696@* @date 4月19日 上午11:58:56*/public class R extends HashMap<String, Object> {private static final long serialVersionUID = 1L;public static final String SUCCESS = "success";public static final String EXCEPTION = "exception";public static final Integer SUCCESSCODE = 0;public static final Integer EXCEPTIONCODE = 500;public R() {put("errCode", 0);put("msg", SUCCESS);}public R(int code, String msg){put("errCode", code);put("msg", msg);}public static R error() {return error(500, "未知异常,请联系管理员");}public static R error(String msg) {return error(500, msg);}public static R error(int code, String msg) {R r = new R();r.put("errCode", code);r.put("msg", msg);return r;}public static R ok(String msg) {R r = new R();r.put("msg", msg);return r;}public static R ok(Map<String, Object> map) {R r = new R();r.putAll(map);return r;}public static R ok() {return new R();}public R put(String key, Object value) {super.put(key, value);return this;}}

View Code

OK,大功告成!整体流程已经搭建起来,读懂了这些代码差不多就明白了整个流程了,然后再看官方文档,你会觉得读起来很顺畅,而不是刚开始那种味同嚼蜡的感觉。你只需再根据官方文档仔细检查检查流程,有没有需要完善的地方,就可以了。

还等什么呢,赶快敲实现功能吧!!!

转载:/hero123/p/9010506.html

推荐内容:

java的@PostConstruct注解

转:Java后端面试自我学习

java加载properties文件的几种方式

java 一次CPU占用过高问题的排查及解决

java后台导出excel代码详细讲解

Java方向如何准备BAT技术面试答案(汇总版)

两道面试题,带你解析Java类加载机制

java BAT最新面试宝典

JAVA日志的前世今生

Java并发之线程池ThreadPoolExecutor源码分析学习

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。