从零用java实现 小红书 springboot vue uniapp (6)用户登录鉴权及发布笔记

前言

移动端演示 http://8.146.211.120:8081/#/

前面的文章我们主要完成了前端页面的开发
从今天开始我们开始前后端业务交互

首先讲解登录

  1. 前端传入手机号(目前演示不做限制)
  2. 后台根据传入的账号确定创建还是直接登录
  3. 返回前端token 前端携带token访问鉴权后的接口

登录代码

bash 复制代码
    @ApiOperation(value = "验证码登陆")
    @ApiOperationSupport(order = 1)
    @PostMapping("/api/checkCode")
    @Transactional
    @OperLog(operModule = "获取验证码",operType = OperType.OTHER,operDesc = "验证码登陆")
    public ResultBean<Author> checkCode(@RequestBody  PhoneLoginDto phoneLoginDto) {
        loginService.checkCode(phoneLoginDto);
       //验证后登陆
        Author author = authorService.selectAuthorByPhoneNumber(phoneLoginDto.getPhoneNumber());
        if(author==null){
            author =  authorService.createNewAuthor(phoneLoginDto.getPhoneNumber());
        }
        //根据用户id生成token
        final String token = jwtTokenUtil.generateTokenByUserId(author.getAuthorId());
        author.setToken(token);
        return ResultBean.success(author);
    }

具体代码中,在 checkCode 方法里,先调用 loginService.checkCode 进行验证登录,接着通过手机号查找用户,若不存在则调用 createNewAuthor 方法创建新用户,之后根据用户 id 生成 token 并设置到用户对象中返回给前端。

创建用户后会随机生成一个人机昵称 规则 形容词 + 名词 +数字 例如(卑微小猪74)小红书号 预设头像 背景 当前登录ip和ip归属

bash 复制代码
    public Author createNewAuthor(String phoneNumber) {
        Author author = new Author();
        author.setPhoneNumber(phoneNumber);
        //随机生成昵称
        author.setAuthorName(RandomXiaohongshuAuthorName.generateAuthorName());
        author.setAuthorNo(StringUtil.getNumberForPK() + StringUtil.createCode(2));
        author.setDescription("我是" + author.getAuthorName());
        //生成随机头像因为没有点击上传所有没有头像id
        author.setAvatarUrl("http://8.146.211.120:8080/upload/avatar/avatar ("+ StringUtil.createCode(1) +").jpg");
        author.setBackGroundUrl("http://8.146.211.120:8080/upload/notes/note (6).jpg");
        author.setIpAddress(IPUtils.getIpAddr(request)); // 请求IP
        author.setIpRealAddress(AddressUtils.getRealAddress(author.getIpAddress())); //ip真实地址
        this.save(author);
        return author;
    }

前端拿到token后每次请求都携带token

bash 复制代码
				// 根据项目需要完成数据验证工作
					app.post('/checkCode', {phoneNumber:this.phoneno,code:formData.pwd}, '','', (res => {
						if(res.code == 200){
							//保存token
							app.setStorage('token',res.data.token)
							app.setStorage('user',res.data)
							app.navigate('/pages/switchPages/index','reLaunch')
						}
					}))

携带token后后台怎么处理呢

我们需要实现一个 拦截器 用于登录后接口的鉴权 判断登录者身份显示相应数据

创建一个拦截器

bash 复制代码
@Configuration
public class GolbalConfig implements WebMvcConfigurer {

    @Autowired
    private ApiInterceptor apiInterceptor;

    // 注册拦截器的方法
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(apiInterceptor)
                .addPathPatterns("/api/auth/**"); // 拦截/api下所有请求路径
    }

}

ApiInterceptor的具体实现

bash 复制代码
@Component
public class ApiInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private AuthorService authorService;

    @Autowired
    HttpServletRequest httpServletRequest;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
       // 预请求过滤
        if(RequestMethod.OPTIONS.name().equals(request.getMethod())) {
            return true;
        }
        String token = request.getHeader("token");
        if (StrUtil.isBlank(token)) {
            throw new ApiException("请登录后访问");
        }
        //解析token
        System.out.println(token);
        String authorId = jwtTokenUtil.getUsernameFromToken(token);
        request.setAttribute("authorId",authorId);

//        Author author = authorService.getById(authorId);
//        request.setAttribute("author",author);
        return true;
    }
}

拦截器有时候会拿不到token 结果发现会有options请求 我们直接返回true if(RequestMethod.OPTIONS.name().equals(request.getMethod())) {
return true;
}

之后 我们就可以通过

bash 复制代码
    @ApiOperation(value = "获取博主信息")
    @ApiOperationSupport(order = 1)
    @GetMapping("/api/auth/getMine")
    @OperLog(operModule = "获取博主信息",operType = OperType.QUERY,operDesc = "获取博主信息")
    public ResultBean<Author> getMine() {
        String authorId = String.valueOf(request.getAttribute("authorId"));
        Author author = authorService.getById(authorId);
        return ResultBean.success(author);
    }

这样的方式获取当前登录者信息了

之后我们就可以创建我们自己的笔记了

点击tab的+号 进入笔记创作页面

基本原理是先上传图片 上传后返回文件id 然后文件id集合和标题内容一并传入后台

一个笔记怎么对应多张图片呢 图片字段不能创建到当前笔记上

需要有一个关联表

传入笔记id 图片id 笔记和图片形成一对多的关系 并加上排序

具体实现

bash 复制代码
   @ApiOperation(value = "创建笔记")
    @ApiOperationSupport(order = 1)
    @PostMapping("/api/auth/addNote")
    @OperLog(operModule = "创建笔记",operType = OperType.ADD,operDesc = "创建笔记")
    public ResultBean addNote(@RequestBody NoteDto noteDto) {
        String authorId = String.valueOf(request.getAttribute("authorId"));
        Author author = authorService.getById(authorId);

        Note note = BeanUtil.copyProperties(noteDto, Note.class);
        note.setAuthorId(author.getAuthorId());
        note.setAuthorName(author.getAuthorName());
        note.setAuthorAvatar(author.getAvatarUrl());
        note.setIpAddress(IPUtils.getIpAddr(request)); // 请求IP
        note.setIpRealAddress(AddressUtils.getRealAddress(note.getIpAddress()));
        noteService.save(note);

        List<String> imgs = noteDto.getImgs();
        List<NoteImg> noteImgList = new ArrayList<>();
        for(int i=0;i<imgs.size();i++){
            NoteImg noteImg = new NoteImg();
            noteImg.setAuthorId(authorId);
            noteImg.setNoteId(note.getNoteId());
            noteImg.setImgSort(i);
            File file = fileService.selectFileByFileId(imgs.get(i));
            String serverName = request.getServerName();
            System.out.println(serverName);
            noteImg.setImgUrl("http://" + serverName + ":" + port + file.getFilePath());
            noteImgList.add(noteImg);
        }
        noteImgService.saveBatch(noteImgList);

        Note updateNote = noteService.getById(note.getNoteId());
        updateNote.setFirstPicture(noteImgList.get(0).getImgUrl());
        noteService.updateById(updateNote);
        return ResultBean.success();
    }

因为是登录后接口 我们已经拿到了作者信息

基本鉴权 创建笔记开发完毕 后续我们完成点赞收藏关注功能

代码地址
https://gitee.com/ddeatrr/springboot_vue_xhs

相关推荐
还是大剑师兰特1 小时前
Vue3 中的 defineExpose 完全指南
前端·javascript·vue.js
大阿明1 小时前
Spring Boot(快速上手)
java·spring boot·后端
哆啦A梦15881 小时前
Springboot整合MyBatis实现数据库操作
数据库·spring boot·mybatis
bearpping1 小时前
Java进阶,时间与日期,包装类,正则表达式
java
邵奈一2 小时前
清明纪念·时光信笺——项目运行指南
java·实战·项目
sunwenjian8862 小时前
Java进阶——IO 流
java·开发语言·python
sinat_255487812 小时前
读者、作家 Java集合学习笔记
java·笔记·学习
皮皮林5512 小时前
如何画出一张优秀的架构图?(老鸟必备)
java
百锦再2 小时前
Java 并发编程进阶,从线程池、锁、AQS 到并发容器与性能调优全解析
java·开发语言·jvm·spring·kafka·tomcat·maven
xkxnq2 小时前
第六阶段:Vue生态高级整合与优化(第93天)Element Plus进阶:自定义主题(变量覆盖)+ 全局配置与组件按需加载优化
前端·javascript·vue.js