微信小程序登录,后端如何处理?

登录凭证验证

1.application.xml配置

weChat:
<!--*处写自己小程序的AppId-->
  appid: ******************
  <!--*处写自己小程序的AppSecret-->	  
  secret: ********************************
  code2Session: https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={js_code}&grant_type=authorization_code

2.微信信息实体类

@Component
@Data
@ConfigurationProperties(prefix = "wechat")
public class WechatConfig {

    private String appid;

    private String secret;

    private String code2Session;

    private String code;


}

3.登录方法

(1)controller层

@Autowired
private WechatConfig wechatConfig;
@PostMapping(value = "/code2Session")
@ApiOperation(value = "小程序 登录凭证校验", notes = "通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程")
public AjaxResult reloadPwd(@RequestBody @ApiParam("登录时获取的 code") WechatConfig weconfig) {

    try {
        Map<String, String> params = new HashMap<>();
        params.put("appid", wechatConfig.getAppid());
        params.put("secret", wechatConfig.getSecret());
        params.put("js_code", weconfig.getCode());
        log.error("微信请求code2Session-->"+ params);
        String result = RestTemplateUtil.getForm(wechatConfig.getCode2Session(), String.class, params);
        log.error("微信返回code2Session-->"+ result);
        if (!WechatUtils.isSuccess(result)) {
            return AjaxResult.error();
        }
        com.alibaba.fastjson.JSONObject resultObj = JSON.parseObject(result);
        //可添加业务逻辑处理
        return AjaxResult.success(resultObj);
    } catch (Exception e) {
        log.error("小程序 登录凭证校验异常:{}", e);
        return AjaxResult.error();
    }
}

(2)RestTemplateUtil工具类

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.util.concurrent.ListenableFutureCallback;
import org.springframework.web.client.AsyncRestTemplate;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;

/**
 * created By DoLaLi on 2021/12/6
 */
public class RestTemplateUtil {
    /**
     * 发送表单参数的post请求
     *
     * @param url      请求url
     * @param param    参数
     * @param respType 返回类型
     * @return T
     */
    public static <T> T postForm(String url, Map<String, List<Object>> param, Class<T> respType) {
        return getRestInstance().postForEntity(url, getHttpEntity(param, false), respType).getBody();
    }

    public static <T> T postFormEx(String url, Map<String, Object> param, Class<T> respType) {
        return getRestInstance().postForEntity(url, param, respType).getBody();
    }

    /**
     * @Description: 发送post json请求
     * @Param: [url, param, respType]
     * @return: T
     * @Author: John.Liu
     * @Date: 2021-03-12
     */
    public static <T> T postJson(String url, Map<String, List<Object>> param, Class<T> respType) {
        return getRestInstance().postForEntity(url, getHttpEntity(param, true), respType).getBody();
    }

    /**
     * @Description: 发送post json请求
     * @Param: [url, param, respType]
     * @return: T
     * @Author: John.Liu
     * @Date: 2021-03-12
     */
    public static <T> T postJsonStr(String url, Map<String, Object> param, Class<T> respType) {
        return getRestInstance().postForEntity(url, getHttpEntity(param, true), respType).getBody();
    }

    /**
     * 发送表单参数的异步post请求
     *
     * @param url      请求url
     * @param callback 回调接口
     * @param respType 返回类型
     */
    public static <T> void asyncPostForm(String url, Map<String, List<Object>> param,
                                         Class<T> respType, ListenableFutureCallback<ResponseEntity<T>> callback) {
        getAsyncRestInstance().postForEntity(url, getHttpEntity(param, false), respType).addCallback(callback);
    }

    /**
     * 发送表单有参数get请求
     *
     * @param url      请求url
     * @param param    参数对象
     * @param respType 返回类型
     * @return T
     */
    public static <T> T getForm(String url, Class<T> respType, Map<String,String> param) {

        return getRestInstance().getForEntity(url, respType, param).getBody();
    }

    /**
     * @Description: 发送表单无参数的get请求
     * @Param: [url, param, respType]
     * @return: T
     * @Author: tonyzhang
     * @Date: 2019-01-18 17:23
     */
    public static <T> T getForm(String url, Class<T> respType) {
        return getRestInstance().getForObject(url, respType);
    }


    /**
     * 获取HttpEntity实例对象
     *
     * @param param  参数对象
     * @param isJson true 发送json请求,false发送表单请求
     * @return HttpEntity
     */
    private static <P> HttpEntity<P> getHttpEntity(P param, boolean isJson) {

        HttpHeaders headers = new HttpHeaders();
        if (isJson) {
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
        } else {
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        }

        return new HttpEntity<>(param, headers);
    }

    /*-----------------生产单例对象,方便自定义如何构造对象------------------*/

    private static RestTemplate restInit() {

        //设置连接超时和读取超时时间
        SimpleClientHttpRequestFactory factory=new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(5000);
        factory.setReadTimeout(5000);
        RestTemplate restTemplate = new RestTemplate(factory);
        FormHttpMessageConverter fastConverter = new FormHttpMessageConverter();
        WxMappingJackson2 wmc=new WxMappingJackson2();
        restTemplate.getMessageConverters().add(fastConverter);
        restTemplate.getMessageConverters().add(wmc);
        return restTemplate;
    }



    private static AsyncRestTemplate asyncRestInit() {
        return new AsyncRestTemplate();
    }

    private static RestTemplate getRestInstance() {
        return RestSingle.INSTANCE;
    }

    private static AsyncRestTemplate getAsyncRestInstance() {
        return AsyncRestSingle.INSTANCE;
    }

    private static class RestSingle {
        private static final RestTemplate INSTANCE = restInit();
    }

    private static class AsyncRestSingle {
        private static final AsyncRestTemplate INSTANCE = asyncRestInit();
    }
}

(3)WxMappingJackson2工具类

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

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

/**
 * created By DoLaLi on 2021/12/6
 * 封装转换器, 添加更多类型的支持
 */
public class WxMappingJackson2 extends MappingJackson2HttpMessageConverter {

    public WxMappingJackson2(){

        List<MediaType> mediaTypes=new ArrayList<>();
        //添加text/html类型的支持
        mediaTypes.add(MediaType.TEXT_HTML);
        //添加text/plain类型的支持.微信接口会用到
        mediaTypes.add(MediaType.TEXT_PLAIN);
        setSupportedMediaTypes(mediaTypes);
    }

}

(4)WechatUtils工具类

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * created By DoLaLi on 2021/12/6
 */
public class WechatUtils {
    public static boolean isSuccess(String result){

        JSONObject jsonObj = JSON.parseObject(result);
        if(jsonObj.containsKey("errcode") && jsonObj.getIntValue("errcode") != 0){

            return false;
        }
        return true;
    }
}

结果

微信返回code2Session-->{"session_key":"R7R2EuVVtSzR5M7iQ9Jxqw==","openid":"ohenl3ZDgBlDN6AFaYl7D9OxRl_2","unionid":"orKka6IeooKvpYwd62T3EL71e3Kc"}
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序登录后端代码主要涉及到以下步骤: 1. 接收小程序前端传来的 code。 2. 使用 code 向微信服务器发送请求,获取 openid 和 session_key。 3. 将 openid 和 session_key 存储到后端数据库,作为用户登录信息。 4. 生成一个 token,作为用户的身份标识,返回给小程序前端。 5. 小程序前端将 token 存储到本地,以便后续的接口调用。 以下是一个基于 Node.js 的示例代码: ```javascript const express = require('express'); const app = express(); const request = require('request'); const APPID = 'your_appid'; const SECRET = 'your_secret'; // 接收小程序前端传来的 code,获取 openid 和 session_key app.get('/wxlogin', function(req, res){ const code = req.query.code; const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${APPID}&secret=${SECRET}&js_code=${code}&grant_type=authorization_code`; request(url, function (error, response, body) { if (!error && response.statusCode == 200) { // 将 openid 和 session_key 存储到后端数据库 const data = JSON.parse(body); const openid = data.openid; const session_key = data.session_key; // 生成 token,返回给小程序前端 const token = generateToken(openid); res.json({ token: token }); } else { res.json({ error: error }); } }) }); function generateToken(openid) { // 生成 token 的代码 return token; } app.listen(3000, function(){ console.log('Server started on port 3000'); }); ``` 需要注意的是,此处的 generateToken 函数需要根据实际需求进行实现。生成 token 的方式可以有很多种,比如使用 JWT 或者自己实现一个简单的 token 算法。此外,存储 openid 和 session_key 的方式也需要根据实际情况进行调整,可以选择存储到数据库或者缓存中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值