zoukankan      html  css  js  c++  java
  • 微信登录4-开发回调URL

    一、准备

    1、引入pom依赖

    在要使用HttpClient的项目中加入依赖

    <!--httpclient-->
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
    </dependency>
    

    2、添加httpclient工具类

    把HttpClientUtils.java放入项目的util包

    /**
     * http请求客户端
     */
    public class HttpClientUtils {
    	private String url;
    	private Map<String, String> param;
    	private int statusCode;
    	private String content;
    	private String xmlParam;
    	private boolean isHttps;
    
    	public boolean isHttps() {
    		return isHttps;
    	}
    
    	public void setHttps(boolean isHttps) {
    		this.isHttps = isHttps;
    	}
    
    	public String getXmlParam() {
    		return xmlParam;
    	}
    
    	public void setXmlParam(String xmlParam) {
    		this.xmlParam = xmlParam;
    	}
    
    	public HttpClientUtils(String url, Map<String, String> param) {
    		this.url = url;
    		this.param = param;
    	}
    
    	public HttpClientUtils(String url) {
    		this.url = url;
    	}
    
    	public void setParameter(Map<String, String> map) {
    		param = map;
    	}
    
    	public void addParameter(String key, String value) {
    		if (param == null)
    			param = new HashMap<String, String>();
    		param.put(key, value);
    	}
    
    	public void post() throws ClientProtocolException, IOException {
    		HttpPost http = new HttpPost(url);
    		setEntity(http);
    		execute(http);
    	}
    
    	public void put() throws ClientProtocolException, IOException {
    		HttpPut http = new HttpPut(url);
    		setEntity(http);
    		execute(http);
    	}
    
    	public void get() throws ClientProtocolException, IOException {
    		if (param != null) {
    			StringBuilder url = new StringBuilder(this.url);
    			boolean isFirst = true;
    			for (String key : param.keySet()) {
    				if (isFirst) {
    					url.append("?");
    					isFirst = false;
    				}else {
    					url.append("&");
    				}
    				url.append(key).append("=").append(param.get(key));
    			}
    			this.url = url.toString();
    		}
    		HttpGet http = new HttpGet(url);
    		execute(http);
    	}
    
    	/**
    	 * set http post,put param
    	 */
    	private void setEntity(HttpEntityEnclosingRequestBase http) {
    		if (param != null) {
    			List<NameValuePair> nvps = new LinkedList<NameValuePair>();
    			for (String key : param.keySet())
    				nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
    			http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
    		}
    		if (xmlParam != null) {
    			http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
    		}
    	}
    
    	private void execute(HttpUriRequest http) throws ClientProtocolException,
    			IOException {
    		CloseableHttpClient httpClient = null;
    		try {
    			if (isHttps) {
    				SSLContext sslContext = new SSLContextBuilder()
    						.loadTrustMaterial(null, new TrustStrategy() {
    							// 信任所有
    							public boolean isTrusted(X509Certificate[] chain,
    									String authType)
    									throws CertificateException {
    								return true;
    							}
    						}).build();
    				SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
    						sslContext);
    				httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
    						.build();
    			} else {
    				httpClient = HttpClients.createDefault();
    			}
    			CloseableHttpResponse response = httpClient.execute(http);
    			try {
    				if (response != null) {
    					if (response.getStatusLine() != null)
    						statusCode = response.getStatusLine().getStatusCode();
    					HttpEntity entity = response.getEntity();
    					// 响应内容
    					content = EntityUtils.toString(entity, Consts.UTF_8);
    				}
    			} finally {
    				response.close();
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		} finally {
    			httpClient.close();
    		}
    	}
    
    	public int getStatusCode() {
    		return statusCode;
    	}
    
    	public String getContent() throws ParseException, IOException {
    		return content;
    	}
    
    }
    
    

    二、获取access_token

    在ApWxiController.java中添加如下方法

        @GetMapping("callback")
        public String callback(String code, String state, HttpSession session){
            System.out.println("callback被调用");
            System.out.println("code:" + code);
            System.out.println("state:" + state);
    
            if(StringUtils.isEmpty(code) || StringUtils.isEmpty(state)){
                log.error("非法回调请求");
                throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
            }
    
            String sessionState = (String)session.getAttribute("wx_open_state");
            if(!state.equals(sessionState)){
                log.error("非法回调请求");
                throw new GuliException(ResultCodeEnum.ILLEGAL_CALLBACK_REQUEST_ERROR);
            }
    
    
            //携带code临时票据,和appid以及appsecret请求access_token和openid(微信唯一标识)
            String accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token";
            //组装参数:?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
            Map<String, String> accessTokenParam = new HashMap<>();
            accessTokenParam.put("appid", ucenterProperties.getAppId());
            accessTokenParam.put("secret", ucenterProperties.getAppSecret());
            accessTokenParam.put("code", code);
            accessTokenParam.put("grant_type", "authorization_code");
            HttpClientUtils client = new HttpClientUtils(accessTokenUrl, accessTokenParam);
    
            String result = "";
            try {
                //发送请求:组装完整的url字符串、发送请求
                client.get();
                //得到响应
                result = client.getContent();
                System.out.println("result = " + result);
            } catch (Exception e) {
                log.error("获取access_token失败");
                throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
            }
    
            Gson gson = new Gson();
            HashMap<String, Object> resultMap = gson.fromJson(result, HashMap.class);
    
            //失败的响应结果
            Object errcodeObj = resultMap.get("errcode");
            if(errcodeObj != null){
                Double errcode = (Double)errcodeObj;
                String errmsg = (String)resultMap.get("errmsg");
                log.error("获取access_token失败:" + "code:" + errcode + ", message:" +  errmsg);
                throw new GuliException(ResultCodeEnum.FETCH_ACCESSTOKEN_FAILD);
            }
    
            //解析出结果中的access_token和openid
            String accessToken = (String)resultMap.get("access_token");
            String openid = (String)resultMap.get("openid");
    
            System.out.println("accessToken:" + accessToken);
            System.out.println("openid:" + openid);
    
            //在本地数据库中查找当前微信用户的信息
            Member member = memberService.getByOpenid(openid);
    
           //TODO
            
            return null;
        }
    

    三、获取用户信息

    1、根据openid查询用户是否已注册

    业务接口:MemberService.java

    /**
         * 根据openid返回用户信息
         * @param openid
         * @return
         */
    Member getByOpenid(String openid);
    

    业务实现:MemberServiceImpl.java

    @Override
    public Member getByOpenid(String openid) {
        QueryWrapper<Member> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("openid", openid);
        return baseMapper.selectOne(queryWrapper);
    }
    

    2、根据access_token获取用户信息

    @Autowired
    private MemberService memberService;
    
    @GetMapping("callback")
    public String callback(String code, String state, HttpSession session){
    			...
           //根据access_token获取微信用户的基本信息
            //根据openid查询当前用户是否已经使用微信登录过该系统
            Member member = memberService.getByOpenid(openid);
            if(member == null){
        
                //向微信的资源服务器发起请求,获取当前用户的用户信息
                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo";
                Map<String, String> baseUserInfoParam = new HashMap();
                baseUserInfoParam.put("access_token", accessToken);
                baseUserInfoParam.put("openid", openid);
                client = new HttpClientUtils(baseUserInfoUrl, baseUserInfoParam);
        
                String resultUserInfo = null;
                try {
                    client.get();
                    resultUserInfo = client.getContent();
                } catch (Exception e) {
                    log.error(ExceptionUtils.getMessage(e));
                    throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
                }
        
                HashMap<String, Object> resultUserInfoMap = gson.fromJson(resultUserInfo, HashMap.class);
                if(resultUserInfoMap.get("errcode") != null){
                    log.error("获取用户信息失败" + ",message:" + resultMap.get("errmsg"));
                    throw new GuliException(ResultCodeEnum.FETCH_USERINFO_ERROR);
                }
        
                String nickname = (String)resultUserInfoMap.get("nickname");
                String headimgurl = (String)resultUserInfoMap.get("headimgurl");
                Double sex = (Double)resultUserInfoMap.get("sex");
        
                //用户注册
                member = new Member();
                member.setOpenid(openid);
                member.setNickname(nickname);
                member.setAvatar(headimgurl);
                member.setSex(sex.intValue());
                memberService.save(member);
            }
        
            JwtInfo jwtInfo = new JwtInfo();
            jwtInfo.setId(member.getId());
            jwtInfo.setNickname(member.getNickname());
            jwtInfo.setAvatar(member.getAvatar());
            String jwtToken = JwtUtils.getJwtToken(jwtInfo, 1800);
        
            //携带token跳转
            return "redirect:http://localhost:3000?token=" + jwtToken;
    }
    

    四、前端整合

    components/AppHeader.vue
    mounted() {
        // 微信登录url token获取
        this.token = this.$route.query.token
        if (this.token) {
            // 将token存在cookie中
            cookie.set('guli_jwt_token', this.token, { domain: 'localhost' })
            // 跳转页面:擦除url中的token
            // 注意:window对象在created方法中无法被访问,因此要写在mounted中
            window.location.href = '/'
        }
    },
    
  • 相关阅读:
    C基础02天——笔记
    C基础-指针和数组等价转换
    C基础04天—选择排序笔记
    C基础-标准C语言头文件
    C基础-C的关键字
    Ubuntu linux 环境基本使用
    C基础01天——常量变量笔记
    根据评分,用js输出评价星星的样式
    横向滚动条展示 css
    ajax 城市区域选择三级联动
  • 原文地址:https://www.cnblogs.com/smalldong/p/13909532.html
Copyright © 2011-2022 走看看