在我们日常开发微信小程序的过程中,难免会遇到小程序登录功能,以下是我的解决方案

注意:微信登录的code和手机号快速登录的code是不一样的

一、前端开发

前端开发我使用的是uniapp,代码如下

template部分:

<!-- #ifdef MP-WEIXIN -->
<button  type="primary" size="mini" v-if="!isLogin" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">手机号一键登录</button>
<!-- #endif -->

script部分:

// 手机号登录
const getPhoneNumber = async (e) => {
    if(e.detail.code == undefined) {
        return
    }else{
        uni.login({
            provider:"weixin",
            success:res=>{
                login(res.code, e.detail.code)
            }
        })
    }    
}
    
// 登录
const login = async (code, p_cpde) => {
    const res = await axios.post(`/login?code=${code}&p_code=${p_cpde}`)
    console.log(res)
    userInfo.value = res.data.data.user
    isLogin.value = true
    // 将信息存入本地
    uni.setStorageSync("token",res.data.data.token)
    uni.setStorageSync("user",res.data.data.user)
    Notify({ type: 'success', message: '登录成功!' });
}

二、后端开发

后端开发我使用的是SpringBoot+MyBatis+MyBatisPlus

其中,需要添加的几个重要依赖:

<dependency>
    <groupId>net.minidev</groupId>
    <artifactId>json-smart</artifactId>
    <version>2.4.8</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.13.4</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.72</version>
</dependency>
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20210307</version>
</dependency>
 
<!--        微信-->
<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-miniapp</artifactId>
    <version>4.5.9.B</version>
</dependency>

接口开发:

controller:

@RestController
public class LoginController {
 
    @Resource
    private LoginService loginService;
 
 
    @PostMapping("/login")
    public Result login(@Param("code") String code,
                        @Param("p_code")String p_code) {
        return loginService.login(code, p_code);
    }
    
}

service:

public interface LoginService {
//    小程序一键登录
    Result login(String code,String p_code);
 
}

serviceImpl:

@Service
public class LoginServiceImpl implements LoginService {
 
    private static final String APPID = "";
    private static final String SECRET = "";
 
    @Resource
    private MiniUserMapper miniUserMapper;
 
    @Override
    public Result login(String code, String p_code) {
        String userPhone = "";
//        判断用户是否授权
        if (code != null) {
             userPhone = getUserPhone(p_code);
        }
        HashMap<String, Object> map = new HashMap<>();
//        将code发送到微信服务器进行登录凭证校验
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid={0}&secret={1}&js_code={2}&grant_type=authorization_code";
        String replaceUrl = url.replace("{0}", APPID).replace("{1}", SECRET).replace("{2}", code);
        String res = HttpUtil.get(replaceUrl);
        // 从微信服务器返回的数据中提取 openid 和 session_key
        // 解析JSON数据
        org.json.JSONObject jsonObject = new JSONObject(res);
        // 提取openid
        String openid = jsonObject.getString("openid");
//        判断判断数据库中是否有该openid记录,有则查询信息返回数据,没有则注册并返回数据
        QueryWrapper<MiniUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("open_id", openid);
        MiniUser miniUser = miniUserMapper.selectOne(userQueryWrapper);
//        判断
        if (miniUser == null){
            // 生成随机6个字符
            String randomStr = new Random().ints('A', 'Z' + 1) // 生成'A'到'Z'之间的随机整数流
                    .limit(6) // 限制生成6个字符
                    .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
                    .toString();
            miniUser = new MiniUser();
            miniUser.setOpenId(openid);
            miniUser.setName("姓名_"+ randomStr);
            miniUser.setPhone(userPhone);
            miniUserMapper.insert(miniUser);
            String token = JWTUtils.generateToken(openid);
            map.put("token", token);
            map.put("user", miniUser);
            return Result.success("登录成功", map);
        }
        if (miniUser != null) {
            String token = JWTUtils.generateToken(miniUser.getOpenId());
            map.put("token", token);
            map.put("user", miniUser);
            return Result.success("登录成功", map);
        }
        return Result.fail("登录失败");
    }
 
    
    public String getUserPhone(String code) {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}&";
        String replaceUrl = url.replace("{0}", APPID).replace("{1}", SECRET);
        String res = HttpUtil.get(replaceUrl);
        org.json.JSONObject jsonObject = new JSONObject(res);
        // 提取access_token
        String access_token = jsonObject.getString("access_token");
//       获取手机号
        String url1 = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={0}";
        String replaceUrl1 = url1.replace("{0}", access_token);
        JSONObject params = new JSONObject();
        params.put("code", code);
        String res1 = HttpUtil.post(replaceUrl1, params.toString());
        JSONObject response = new JSONObject(res1);
         // 提取 phone_info
         JSONObject phoneInfo = response.getJSONObject("phone_info");
         String phoneNumber = phoneInfo.getString("phoneNumber");
         return phoneNumber;
    }
}

实体:MiniUser

@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("mini_user")
public class MiniUser {
 
    @TableId(value = "mini_user_id",type = IdType.AUTO)
    private Integer miniUserId;// 用户id
 
    private String openId;// openId
 
    private String name; // 姓名
 
    private String phone;// 手机号
 
    private String password; // 密码
 
    private String createTime; // 创建时间
 
    private String updateTime; // 更新时间
 
    private Integer status; // 状态(1-正常、2-冻结)
 
}

mapper:MiniUserMapper

public interface MiniUserMapper extends BaseMapper<MiniUser> {}

三、测试

07a5636b00174233938e7db7fd73e34b.png

最后修改:2024 年 10 月 15 日
如果觉得我的文章对你有用,请随意赞赏