调用微信接口实现微信授权登陆主体内容【code换取openid以及session_key】

目前实现微信授权登陆分以下几个部分:
1️⃣:调取微信wx.login()接口获取code
关于code:在这里插入图片描述
在这里插入图片描述
2️⃣将code通过微信wx.request()接口传到后台,然后将code、appid、secret拼接之后传给微信服务器,从而换取上述openid及本次会话秘钥session_key等。
在这里插入图片描述
上述接口中:
1.url为后台接口地址。
2.data为本次会话要传递的数据,例如将code传入后台
3.header为请求头部行,关于这个,在微信的官方文档中即图片中’application/json’已经不是最新的,目前微信已经更新这个请求头部行,最新的头部行为

 header: {
            'Content-Type': 'application/x-www-form-urlencoded' // 默认值
          }

如果上述请求头部行不正确,在发起网络请求时会报400错误(Bad Request)错误请求!
上述代码中也要加上请求方式为POST请求
完整代码如下:

    wx.login({
      success (res) {
        console.log("code"+"==="+res.code)
        wx.request({
          url: 'http://localhost:1314/wx/login', //并非真实的接口地址,此处采用本机作为服务器示例!!!
          method: 'POST',
          data: {
            code:res.code
          },
          header: {
            'Content-Type': 'application/x-www-form-urlencoded' // 默认值
          },
          success (res) {
            console.log(res.data)
          }
        })
      }
    })

前端目前只需要这些内容~
3️⃣后端接收前端传来的code并请求微信服务器换取openid等。【springboot】
tips:如果不会spring的请看我的一篇springboot入门案例,授权登陆牵扯到的springboot并不深入,可以简要了解
此篇文章采取两种方式给大家讲解(主要区别在于发起请求的方式!没必要的话可以只用一种!!!):
(一):
包结构如下:
在这里插入图片描述

第一种方法请忽略图中config包,采用utils工具类封装好的http请求工具类
无法导入文件,在此我将两个文件的代码写在下面(太长了,请忽略直接复制粘贴!):
HttpClientUtil:

package com.java1234.util;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * httpClient 工具类
 * @author java1234_小锋
 * @site www.java1234.com
 * @company Java知识分享网
 * @create 2019-02-10 下午 2:49
 */
@Component
public class HttpClientUtil {
	
	/**
	 * 默认参数设置
	 * setConnectTimeout:设置连接超时时间,单位毫秒。
	 * setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。
	 * setSocketTimeout:请求获取数据的超时时间,单位毫秒。访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。 暂时定义15分钟
	 */
	private RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(600000).setConnectTimeout(600000).setConnectionRequestTimeout(600000).build();
	
	/**
	 * 静态内部类---作用:单例产生类的实例
	 * @author Administrator
	 *
	 */
	private static class LazyHolder {    
       private static final HttpClientUtil INSTANCE = new HttpClientUtil();    
       
    }  
	private HttpClientUtil(){}
	public static HttpClientUtil getInstance(){
		return LazyHolder.INSTANCE;    
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 */
	public String sendHttpPost(String httpUrl) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 * @param params 参数(格式:key1=value1&key2=value2)
	 */
	public String sendHttpPost(String httpUrl, String params) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		try {
			//设置参数
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 * @param maps 参数
	 */
	public String sendHttpPost(String httpUrl, Map<String, String> maps) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		// 创建参数队列  
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : maps.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送Post请求
	 * @param httpPost
	 * @return
	 */
	private String sendHttpPost(HttpPost httpPost) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例
			httpClient = HttpClients.createDefault();
			httpPost.setConfig(requestConfig);
			// 执行请求
			long execStart = System.currentTimeMillis();
			response = httpClient.execute(httpPost);
			long execEnd = System.currentTimeMillis();
			System.out.println("=================执行post请求耗时:"+(execEnd-execStart)+"ms");
			long getStart = System.currentTimeMillis();
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
			long getEnd = System.currentTimeMillis();
			System.out.println("=================获取响应结果耗时:"+(getEnd-getStart)+"ms");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	/**
	 * 发送 get请求
	 * @param httpUrl
	 */
	public String sendHttpGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGet(httpGet);
	}
	
	/**
	 * 发送 get请求Https
	 * @param httpUrl
	 */
	public String sendHttpsGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpsGet(httpGet);
	}
	
	/**
	 * 发送Get请求
	 * @param httpGet
	 * @return
	 */
	private String sendHttpGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.

			
			httpClient = HttpClients.createDefault();

			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	/**
	 * 发送Get请求Https
	 * @param httpGet
	 * @return
	 */
	private String sendHttpsGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString()));
			DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
			httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();
			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	/**
	 * 发送xml数据
	 * @param url
	 * @param xmlData
	 * @return
	 * @throws ClientProtocolException
	 * @throws IOException
	 */
	public static HttpResponse sendXMLDataByPost(String url, String xmlData)
			throws ClientProtocolException, IOException {
		HttpClient httpClient = HttpClients.createDefault();
		HttpPost httppost = new HttpPost(url);
		StringEntity entity = new StringEntity(xmlData);
		httppost.setEntity(entity);
		httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");
		HttpResponse response = httpClient.execute(httppost);
		return response;
	}

	/**
	 * 获得响应HTTP实体内容
	 *
	 * @param response
	 * @return
	 * @throws IOException
	 * @throws UnsupportedEncodingException
	 */
	public static String getHttpEntityContent(HttpResponse response) throws IOException, UnsupportedEncodingException {
		HttpEntity entity = response.getEntity();
		if (entity != null) {
			InputStream is = entity.getContent();
			BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
			String line = br.readLine();
			StringBuilder sb = new StringBuilder();
			while (line != null) {
				sb.append(line + "\n");
				line = br.readLine();
			}
			return sb.toString();
		}
		return "";
	}


}

StringUtil(为字符串处理文件,和授权登陆也没有关系,忘记删除了,分享给大家叭):

package com.mjc.boot.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 字符串工具类
 * @author
 *
 */
public class StringUtil {

	/**
	 * 判断是否是空
	 * @param str
	 * @return
	 */
	public static boolean isEmpty(String str){
		if(str==null||"".equals(str.trim())){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 判断是否不是空
	 * @param str
	 * @return
	 */
	public static boolean isNotEmpty(String str){
		if((str!=null)&&!"".equals(str.trim())){
			return true;
		}else{
			return false;
		}
	}

	/**
	 * 格式化模糊查询
	 * @param str
	 * @return
	 */
	public static String formatLike(String str){
		if(isNotEmpty(str)){
			return "%"+str+"%";
		}else{
			return null;
		}
	}

	/**
	 * 过滤掉集合里的空格
	 * @param list
	 * @return
	 */
	public static List<String> filterWhite(List<String> list){
		List<String> resultList=new ArrayList<String>();
		for(String l:list){
			if(isNotEmpty(l)){
				resultList.add(l);
			}
		}
		return resultList;
	}

	/**
	 * 去除html标签
	 */
	public static String stripHtml(String content) {
	    // <p>段落替换为换行
	    content = content.replaceAll("<p .*?>", "\r\n");
	    // <br><br/>替换为换行
	    content = content.replaceAll("<br\\s*/?>", "\r\n");
	    // 去掉其它的<>之间的东西
	    content = content.replaceAll("\\<.*?>", "");
	    // 去掉空格
	    content = content.replaceAll(" ", "");
	    return content;
	}

	/**
	 * 生成六位随机数
	 * @return
	 */
	public static String genSixRandomNum(){
		Random random = new Random();
		String result="";
		for (int i=0;i<6;i++)
		{
			result+=random.nextInt(10);
		}
		return result;
	}

	/**
	 * 生成由[A-Z,0-9]生成的随机字符串
	 * @param length  欲生成的字符串长度
	 * @return
	 */
	public static String getRandomString(int length){
		Random random = new Random();

		StringBuffer sb = new StringBuffer();

		for(int i = 0; i < length; ++i){
			int number = random.nextInt(2);
			long result = 0;

			switch(number){
				case 0:
					result = Math.round(Math.random() * 25 + 65);
					sb.append(String.valueOf((char)result));
					break;
				case 1:

					sb.append(String.valueOf(new Random().nextInt(10)));
					break;
			}
		}
		return sb.toString();
	}


}

同时pom.xml文件里要导入

<!-- 添加Httpclient支持 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.40</version>
        </dependency>

以此来支持网络请求
至此准备工作结束:开始编写Controller

@RestController
@RequestMapping("/wx")
public class getopenid{


    @Autowired
   private HttpClientUtil httpClientUtil;


    @PostMapping("/login")
    public String  wxLogin(@RequestParam("code")String code){
    	//用自己的小程序信息
        String appid="你的小小程序appid";
        String secret="你的小程序secret";
        //拼接sql
        String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid +
                "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";

        String result = httpClientUtil.sendHttpGet(loginUrl);

        System.out.println(result);

        JSONObject jsonObject = JSON.parseObject(result);//将json字符串转化为jsonobject
        String openid = jsonObject.get("openid").toString(); // 获取openId

        System.out.println(openid);

        return "hello";

    }
}

对上述代码的解释:
关于几个注解,需要知道的可以去学一下springboot及注解,在这不做赘述
我们刚才写的HttpClientUtil已经被丢到容器中,然后注入一下,对应下面这步
在这里插入图片描述
然后就是编写方法,通过得到code,再加上已知的appid和secret,如果secret忘记可以去微信小程序官网重置!
然后拼接成sql,对应下面这步
在这里插入图片描述
然后向微信服务器发起网络请求
在这里插入图片描述
至此,请求成功之后微信会返回给我们一个结果,就是result
我们打印一下result来看
在这里插入图片描述
可见包含session_key和openid,且为json格式
我们通过对格式进行解析分别获得openid和session_key,采用JSONObject,不懂的话可以自行百度~
在这里插入图片描述
之后打印就会分别打印出来,我们将结果进行存储,可以采取map集合存储最后返回给前台map集合即可。由于我并没有做这些步骤,不在演示。
由于要返回map集合,上述代码有些部分要更改:

   public Map<String, Object>  wxLogin(@RequestParam("code")String code){
        String appid="你的小程序appid";
        String secret="你的小程序secret";
        //拼接sql
        String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appid +
                "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";

        String result = httpClientUtil.sendHttpGet(loginUrl);

        System.out.println(result);

        JSONObject jsonObject = JSON.parseObject(result);//将json字符串转化为jsonobject
        String openid = jsonObject.get("openid").toString(); // 获取openId
        String session_key = jsonObject.get("session_key").toString();
        System.out.println(openid);
        System.out.println(session_key);
        Map<String,Object> resultMap=new HashMap<>();
        resultMap.put("openid",openid);
        resultMap.put("session_key",session_key);
        return resultMap;

    }

至此,我们演示一下
后台:
在这里插入图片描述
可以看到,解析出来openid和session_key并且打印出来

前台:
在这里插入图片描述
后台已经将集合返回给前台,前台也获取到了
这就是方法(一)实现

(二):
方法二和方法一的区别在于实现网络请求的部分不同,如果不必要!可以不用看!
springboot提供了一个模板:RestTemplate
还记得我们忽略的config包吗
在这里插入图片描述

package com.mjc.boot.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class LoginConfig {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

代码中:
将该类作为springboot的配置类,采用注解@Configuration
@Bean将方法丢到容器中

然后我们在刚才的Controller中
注入这个模板
在这里插入图片描述
并且采用这个对象里的方法进行网络请求就可以了!!
在这里插入图片描述
其余部分和方法一一样!

☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
至此调用微信接口实现授权登录主体内容就是上面所述,至于登录态控制和将用户信息存入数据库本例未涉及,可以自行编写!
本例也是自己和朋友钻研的结果,之前很是头疼,可以说手把手,nt式教学,不懂的宝贝们评论区见~~
再见再见再见~

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值