若依增加登录接口,采用另一张表做登录验证,沿用之前的token规则

该文章详细介绍了如何在后端使用SpringSecurity框架为微信小程序创建登录接口。主要步骤包括在控制器中添加接口处理登录请求,实现WxLoginService进行用户验证,使用WxAuthenticationProvider自定义认证提供者,以及UserDetailsService加载用户详情。同时,更新LoginUser类以适应小程序登录,并在SecurityConfig中配置相关组件。
摘要由CSDN通过智能技术生成

①在控制类中添加接口

@PostMapping("/addUserInfo")
    public AjaxResult addUserInfo(@RequestBody UserInfoDto userInfoDto) throws Exception {
       
            return AjaxResult.success(wxLoginService.wxLogin(userInfoDto.getName(),userInfoDto.getIdentityNumber()));
       
    }

②添加WxLoginService类文件

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class WxLoginService {

    @Resource
    private WxAuthenticationProvider authenticationManager;

    @Autowired
    private TokenService tokenService;

    /**
     * 小程序登录验证
     * @param username
     * @param password
     * @return
     */
    public String wxLogin(String username, String password) throws Exception {
        // 用户验证
        Authentication authentication = null;
        LoginUser loginUser = null;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        if(authentication != null){
             loginUser = (LoginUser) authentication.getPrincipal();
        }else {
            throw new Exception("账号密码错误");
        }
        // 生成token
        return tokenService.createToken(loginUser);
    }
}

③添加WxAuthenticationProvider 文件

import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import java.util.Collection;

@Component
public class WxAuthenticationProvider implements AuthenticationProvider {


    @Autowired
    private WxUserDetailsServiceImpl userDetailsService;

    @SneakyThrows
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        String userName = authentication.getName();// 这个获取表单输入中返回的用户名;
        Object password = authentication.getCredentials();//这个获取表单输入中返回的密码;

        // 这里构建来判断用户是否存在和密码是否正确
        UserDetails userInfo = userDetailsService.loadUserByUsername(userName); // 这里调用我们的自己写的获取用户的方法;
        String pwd =  userInfo.getPassword();
        if(!password.toString().equals(pwd.substring(pwd.length() - 6, pwd.length()))){
            throw new Exception("用户不存在/密码错误");
        }

        Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities();
        // 构建返回的用户登录成功的token
        return new UsernamePasswordAuthenticationToken(userInfo, userInfo.getPassword(), authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

}

④添加UserDetailsService 实现类

import com.ruoyi.common.core.domain.entity.WxUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.PojoUtil;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.construction.domain.vo.PersonnelInformationVo;
import com.ruoyi.construction.service.impl.ConstructionPersonnelInformationServiceImpl;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

@Service
public class WxUserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private ConstructionPersonnelInformationServiceImpl constructionPersonnelInformationService;//自己写的接口

    @Autowired
    private SysPermissionService permissionService;

    @SneakyThrows
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        PersonnelInformationVo personnelInformationVo = constructionPersonnelInformationService.selectConstructionPersonnelInformationByName(username);//验证登录用户

        if (StringUtils.isNull(personnelInformationVo)) {
            throw new Exception("登录用户不存在");
        }
        return createLoginUser(personnelInformationVo);
    }

    public UserDetails createLoginUser(PersonnelInformationVo personnelInformationVo) {
        WxUser wxUser = PojoUtil.copyBean(personnelInformationVo, WxUser.class);
        wxUser.setUserName(personnelInformationVo.getName());
        wxUser.setPassword(personnelInformationVo.getIdentityNumber());
        //权限方式可以默认为所有
        return new LoginUser(wxUser, permissionService.WxGetMenuPermission());
    }
}

⑤在LoginUser中添加对应的用户信息属性,并修改username和password的get方法

 /**
     * wx用户信息
     */
    private WxUser wxUser;
    
     public LoginUser(WxUser wxUser, Set<String> permissions)
    {
        this.wxUser = wxUser;
        this.permissions = permissions;
    }
    @Override
    public String getPassword()
    {
        if(user != null){
            return user.getPassword();
        }else {
            return wxUser.getPassword();
        }

    }
    @Override
    public String getUsername()
    {
        if(user != null){
            return user.getUserName();
        }else {
            return wxUser.getUserName();
        }
    }

⑤需要在 xxx-framework/src/main/java/…/SecurityConfig中添加条件 @Qualifier(“userDetailsServiceImpl”)

在这里插入图片描述

到此就可以实现小程序获取app用户的登录接口了~

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值