当前位置: 首页 > article >正文

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

前言

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

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

首先讲解登录

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

登录
登录代码

    @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归属

    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

				// 根据项目需要完成数据验证工作
					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后后台怎么处理呢
我们需要实现一个 拦截器 用于登录后接口的鉴权 判断登录者身份显示相应数据
创建一个拦截器

@Configuration
public class GolbalConfig implements WebMvcConfigurer {

    @Autowired
    private ApiInterceptor apiInterceptor;

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

}

ApiInterceptor的具体实现

@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;
}

之后 我们就可以通过

    @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 笔记和图片形成一对多的关系 并加上排序
具体实现

   @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


http://www.kler.cn/a/452304.html

相关文章:

  • 第十七届山东省职业院校技能大赛 中职组“网络安全”赛项任务书正式赛题
  • Git--tag标签远程管理
  • 【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo
  • MyBatis-Plus分页拦截器,源码的重构(重构total总数的计算逻辑)
  • 探索多模态大语言模型(MLLMs)的推理能力
  • 计算机基础知识复习12.24
  • 【Trick】解决服务器cuda报错——RuntimeError: cuDNN error: CUDNN_STATUS_NOT_INITIALIZED
  • 前端三大主流框架:React、Vue、Angular
  • 网络管理-期末项目(附源码)
  • PySide6如何实现点击TableWidget列表头在该列右侧显示列表选择框筛选列数据
  • 数据仓库是什么?数据仓库简介
  • 设计一个自己的AI Agent
  • .NET 9 中的 多级缓存 HybridCache
  • Android绘图Path基于LinearGradient线性动画渐变,Kotlin(2)
  • HarmonyOS NEXT 实战之元服务:静态案例效果---电台推荐
  • 【1224】数据结构(sizeof/数组的长度定义/读取字符串函数/线性表长度/左值右值/静态变量/指针与引用)
  • WPF自定义窗口 输入验证不生效
  • SpringBoot3-第四篇(基础特性)
  • Mybatisplus如何使用selectPage
  • 接口测试Day03-postman断言关联
  • HuaWei、NVIDIA 数据中心 AI 算力对比
  • 谈谈JSON
  • DigitalOcean Droplet 云服务器:新增自动扩展池功能
  • npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
  • openwrt 负载均衡方法 openwrt负载均衡本地源接口
  • 08 Django - Django媒体文件静态文件文件上传