Java后端的登录、注册接口是怎么实现的
目录
Java后端的登录、注册接口是怎么实现的
Java后端的登录接口是怎么实现的
Java后端的注册接口怎么实现?
如何防止SQL注入攻击?
Java后端的登录、注册接口是怎么实现的
Java后端的登录接口是怎么实现的
Java后端的登录接口的实现方式有很多种,这里介绍其中一种常见的方式。
-
Cookie + Session 方式:用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。如果验证通过,后端会生成一个session id,然后将session id 以及其他用户信息存储在服务端的session中。同时,后端会将session id 返回给前端,前端将session id 存储在cookie中。之后,前端每次请求时都会带上cookie,后端会根据cookie中的session id 来判断用户是否已经登录,如果已经登录,则返回用户信息,否则返回未登录状态。
-
Token 方式:用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。如果验证通过,后端会生成一个token,然后将token 返回给前端。之后,前端每次请求时都会带上token,后端会根据token来判断用户是否已经登录,如果已经登录,则返回用户信息,否则返回未登录状态。Token 方式相对于 Cookie + Session 方式,具有更好的可扩展性和更好的跨域支持。
基于spring boot+mybatis+vue,结合 JWT 进行 token 的生成和验证,后端代码可以按照以下步骤进行编写:
-
添加依赖:在pom.xml文件中添加spring-boot-starter-security和jjwt依赖。
-
配置Spring Security:在Spring Security配置类中添加JWT过滤器,用于生成和验证token。
-
编写登录接口:在Controller中编写登录接口,接收用户名和密码,验证通过后生成token并返回给前端。
-
编写拦截器:在拦截器中验证token的有效性,如果token无效则返回错误信息。
-
编写注销接口:在Controller中编写注销接口,用于注销当前用户的token。
-
编写token生成工具类:编写一个工具类,用于生成和解析token。
-
编写用户认证逻辑:编写用户认证逻辑,用于验证用户的身份信息。
使用Spring Boot + MyBatis + JWT:
@RestController
@RequestMapping("/api")
public class LoginController {@Autowiredprivate UserService userService;@PostMapping("/login")public ResponseEntity<?> login(@RequestBody User user) {User loginUser = userService.login(user);if (loginUser != null) {String token = JWT.create().withAudience(loginUser.getId().toString()).sign(Algorithm.HMAC256(loginUser.getPassword()));return ResponseEntity.ok(token);} else {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();}}
}
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserService userService;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/api/login").permitAll().anyRequest().authenticated().and().addFilter(new JWTAuthenticationFilter(authenticationManager())).addFilter(new JWTAuthorizationFilter(authenticationManager(), userService)).sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userService).passwordEncoder(passwordEncoder());}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Overridepublic void configure(WebSecurity web) throws Exception {web.ignoring().antMatchers("/swagger-ui.html", "/swagger-resources/**", "/v2/api-docs", "/webjars/**");}
}
public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {private AuthenticationManager authenticationManager;public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {this.authenticationManager = authenticationManager;setFilterProcessesUrl("/api/login");}@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {try {User user = new ObjectMapper().readValue(request.getInputStream(), User.class);return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));} catch (IOException e) {throw new RuntimeException(e);}}@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {User user = (User) authResult.getPrincipal();String token = JWT.create().withAudience(user.getId().toString()).sign(Algorithm.HMAC256(user.getPassword()));response.addHeader("Authorization", "Bearer " + token);}
}
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {private UserService userService;public JWTAuthorizationFilter(AuthenticationManager authenticationManager, UserService userService) {super(authenticationManager);this.userService = userService;}@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {String header = request.getHeader("Authorization");if (header == null || !header.startsWith("Bearer ")) {chain.doFilter(request, response);return;}UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(request);SecurityContextHolder.getContext().setAuthentication(authenticationToken);chain.doFilter(request, response);}private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {String token = request.getHeader("Authorization");if (token != null) {String userId = JWT.require(Algorithm.HMAC256(userService.getById(Long.parseLong(JWT.decode(token.replace("Bearer ", "")).getAudience())).getPassword())).build().verify(token.replace("Bearer ", "")).getAudience().get(0);if (userId != null) {User user = userService.getById(Long.parseLong(userId));return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());}return null;}return null;}
}
@Service
public class UserServiceImpl implements UserService, UserDetailsService {@Autowiredprivate UserMapper userMapper;@Overridepublic User login(User user) {User loginUser = userMapper.getByUsername(user.getUsername());if (loginUser != null && new BCryptPasswordEncoder().matches(user.getPassword(), loginUser.getPassword())) {return loginUser;}return null;}@Overridepublic User getById(Long id) {return userMapper.getById(id);}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userMapper.getByUsername(username);if (user == null) {throw new UsernameNotFoundException("User not found with username: " + username);}return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), new ArrayList<>());
Java后端的注册接口怎么实现?
Java后端的注册接口的实现方式有很多种,这里介绍其中一种常见的方式。
一般来说,注册接口需要进行数据库的基本操作,而且是前后端分离式开发。总的来说就是首先进行数据库的设计,然后根据数据库进行编写服务端API接口,接着来到客户端或移动端,进行登录与注册的界面设计,接收服务端提供的数据并显示在界面上。
以下是一个简单的注册接口实现方式:
- POST请求方式:用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。如果验证通过,后端会将用户信息存储在数据库中。同时,后端会将用户信息返回给前端,前端将用户信息存储在本地。之后,前端每次请求时都会带上用户信息,后端会根据用户信息来判断用户是否已经注册,如果已经注册,则返回用户信息,否则返回未注册状态。
如何防止SQL注入攻击?
SQL注入攻击是一种常见的网络攻击方式,它可以通过恶意的SQL语句来篡改数据库或者获取敏感信息。以下是一些防止SQL注入攻击的方法:
-
使用参数化查询:使用参数化查询可以将用户输入的数据与SQL语句分离,从而避免了SQL注入攻击。在Java中,可以使用PreparedStatement类来实现参数化查询。
-
过滤用户输入:在用户输入数据之前,对数据进行过滤和验证,确保数据的合法性和安全性。例如,可以使用正则表达式来限制用户输入的字符集。
-
使用ORM框架:ORM框架可以自动将用户输入的数据转换为SQL语句,从而避免了手动编写SQL语句的风险。例如,Hibernate和MyBatis都是常用的ORM框架。
-
限制数据库用户权限:将数据库用户的权限限制在最小范围内,只允许其执行必要的操作,可以减少SQL注入攻击的危害。
-
使用存储过程:存储过程可以将SQL语句封装在一个过程中,从而避免了手动编写SQL语句的风险。此外,存储过程还可以提高SQL语句的执行效率。
相关文章:
Java后端的登录、注册接口是怎么实现的
目录 Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的注册接口怎么实现? 如何防止SQL注入攻击? Java后端的登录、注册接口是怎么实现的 Java后端的登录接口是怎么实现的 Java后端的登录接口的实现方式有很多种&a…...
TCP Keepalive 和 HTTP Keep-Aliv
HTTP的Keep-Alive 在http1.0的版本中,它是基于请求-应答模型和TCP协议的,也就是在建立TCP连接后,客户端发送一次请求并且接收到响应后,就会立马断开TCP连接,称为HTTP短连接,这种方式比较耗费时间以及浪费资…...
操作系统 复习笔记
操作系统的目标和作用 操作系统的目标 1.方便性 2.有效性 3.可扩展性 4.开放性 操作系统的作用 1.OS作为用户与计算机硬件系统之间的接口 2.OS作为计算机系统资源的管理者 3.OS实现了对计算机系统资源的抽象 推动操作系统发展的主要动力 1.不断提高计算机系统资源的…...
Java中实现单例模式的方式
1. 使用静态内部类实现单例模式 在Java中,使用静态内部类实现单例模式是一种常见而又有效的方式。这种方式被称为“静态内部类单例模式”或者“Holder模式”。这种实现方式有以下优点: 懒加载(Lazy Initialization):静…...
Vue3-01-创建项目
环境准备 1.需要用到 16.0 以及更高版本的 node.js 2.使用vscode编辑器进行项目开发可以在命令行中查看node的版本号: node -v创建项目 1.准备一个目录 例如,我创建项目的时候是在该目录下进行的;D:\projectsTest\vue3project2.执行创建命令(*&#x…...
Go 语言中的反射机制
欢迎大家到我的博客浏览,更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见,但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单,所以它没有特别强的表达能…...
[leetcode 前缀和]
525. 连续数组 M :::details 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。 示例 1: 输入: nums [0,1] 输出: 2 说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。示例 2: 输入: nums [0,1,0] 输出: …...
Python与ArcGIS系列(十五)根据距离抓取字段
目录 0 简述1 实例需求2 arcpy开发脚本0 简述 在处理gis数据的时候,会遇到这种需求:将一个图层与另一个图层中相近的要素进行字段赋值。本篇将介绍如何利用arcpy及arcgis的工具箱实现这个功能。 1 实例需求 为了介绍这个功能的实现,我们需要有一个特定的功能需求。在这里选…...
YOLOv8分割训练及分割半自动标注
YOLOv8是基于目标检测算法YOLOv5的改进版,它在YOLOv5的基础上进行了优化和改进,加入了一些新的特性和技术,如切片注意力机制、骨干网络的选择等。 本文以yolov8-seg为基准,主要整理分割训练流程及使用v8分割模型进行半自动标注的过程。 一、v8-seg训练 1.1 环境配置 github…...
jsp页面通过class或者id获取a标签上的属性的值
要通过class和id两种方式获取a标签上的某个属性的值,或者给其赋值,可以使用JavaScript。以下是两种方法的示例: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name&q…...
题目:美丽的区间(蓝桥OJ 1372)
题目描述: 解题思路: 采用双指针的快慢指针。 图解 可以采用前缀和,但会相较麻烦。 题解: #include<bits/stdc.h> using namespace std;const int N 1e5 9; int a[N];// 因为是连续区间(连续区间࿱…...
解决:During handling of the above exception, another exception occurred
解决:During handling of the above exception, another exception occurred 文章目录 解决:During handling of the above exception, another exception occurred背景报错问题报错翻译报错位置代码报错原因解决方法参考内容:今天的分享就到…...
计算机基础知识65
cookie和session的使用 # 概念:cookie 是客户端浏览器上的键值对 # 目的:为了做会话保持 # 来源:服务端写入的,服务端再返回的响应头中写入,浏览器会自动取出来 存起来是以key value 形式,有过期时间、path…...
Python开发运维:Python垃圾回收机制
目录 一、理论 1.Python垃圾回收机制 一、理论 1.Python垃圾回收机制 (1)引⽤计数器 1)环状双向链表 refchain 在python程序中创建的任何对象都会放在refchain链表中。 name "david" age 20 hobby ["篮球",游泳…...
ros2/ros安装ros-dep||rosdep init错误
第一个错误的做法: sudo apt-get install python3-pip sudo pip3 install 6-rosdep sudo 6-rosdep 如果使用上述代码将会摧毁整个系统,不重装系统反正我是搞不定啊,因为我不知道那个写软件的人到底做了什么。因为这个我安装的版本是humble&…...
《深入理解计算机系统》学习笔记 - 第四课 - 机器级别的程序
Lecture 05 Machine Level Programming I Basics 机器级别的程序 文章目录 Lecture 05 Machine Level Programming I Basics 机器级别的程序intel 处理器的历史和体系结构芯片的构成AMD 公司(Advanced Micro Devices,先进的微型设备) C, 汇编, 机器代码定义汇编/机器…...
云原生(Cloud Native)——概念,技术,背景,优缺点,实践例子
云原生(Cloud Native)是一种构建和运行应用程序的方法,这些应用程序充分利用云计算的优势。云原生应用程序通常设计为在现代、动态的环境中运行,如公共云、私有云和混合云。这种方法强调微服务架构、容器化、自动化、易于管理和可…...
ElasticSearch之线程池
ElasticSearch节点可用的CPU核的数量,通常可以交给ElasticSearch来自行检测和判定,另外可以在elasticsearch.yml中显式指定。样例如下: node.processors: 2如下表格中的processors即CPU核的数量。 线程池的列表 线程池名称类型线程数量队列…...
StoneDB-8.0-V2.2.0 企业版正式发布!性能优化,稳定性提升,持续公测中!
11月,StoneDB 新版本如期而至,这一个月来我们的研发同学加班加点,持续迭代:在 2.2.0 版本中,我们针对用户提出的需求和做出了重量级更新,修复了一些已知和用户反馈的 Bug,同时对部分代码进行…...
【数据结构 — 排序 — 插入排序】
数据结构 — 排序 — 插入排序 一.排序1.1.排序的概念及其运用1.1.1排序的概念1.1.2排序运用1.1.3 常见的排序算法 二.插入排序2.1.直接插入排序2.1.1.算法讲解2.1.2.代码实现2.1.2.1.函数定义2.1.2.2.算法接口实现2.1.2.3.测试代码实现2.1.2.4.测试展示 2.2.希尔排序2.2.1.算法…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
