商城的網(wǎng)站建設(shè)公關(guān)服務(wù)
目錄
Java后端的登錄、注冊接口是怎么實現(xiàn)的
Java后端的登錄接口是怎么實現(xiàn)的
Java后端的注冊接口怎么實現(xiàn)?
如何防止SQL注入攻擊?
Java后端的登錄、注冊接口是怎么實現(xiàn)的
Java后端的登錄接口是怎么實現(xiàn)的
Java后端的登錄接口的實現(xiàn)方式有很多種,這里介紹其中一種常見的方式。
-
Cookie + Session 方式:用戶輸入用戶名和密碼,前端將用戶提交的用戶名和密碼發(fā)送到后端進行驗證。如果驗證通過,后端會生成一個session id,然后將session id 以及其他用戶信息存儲在服務(wù)端的session中。同時,后端會將session id 返回給前端,前端將session id 存儲在cookie中。之后,前端每次請求時都會帶上cookie,后端會根據(jù)cookie中的session id 來判斷用戶是否已經(jīng)登錄,如果已經(jīng)登錄,則返回用戶信息,否則返回未登錄狀態(tài)。
-
Token 方式:用戶輸入用戶名和密碼,前端將用戶提交的用戶名和密碼發(fā)送到后端進行驗證。如果驗證通過,后端會生成一個token,然后將token 返回給前端。之后,前端每次請求時都會帶上token,后端會根據(jù)token來判斷用戶是否已經(jīng)登錄,如果已經(jīng)登錄,則返回用戶信息,否則返回未登錄狀態(tài)。Token 方式相對于 Cookie + Session 方式,具有更好的可擴展性和更好的跨域支持。
基于spring boot+mybatis+vue,結(jié)合 JWT 進行 token 的生成和驗證,后端代碼可以按照以下步驟進行編寫:
-
添加依賴:在pom.xml文件中添加spring-boot-starter-security和jjwt依賴。
-
配置Spring Security:在Spring Security配置類中添加JWT過濾器,用于生成和驗證token。
-
編寫登錄接口:在Controller中編寫登錄接口,接收用戶名和密碼,驗證通過后生成token并返回給前端。
-
編寫攔截器:在攔截器中驗證token的有效性,如果token無效則返回錯誤信息。
-
編寫注銷接口:在Controller中編寫注銷接口,用于注銷當(dāng)前用戶的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后端的注冊接口怎么實現(xiàn)?
Java后端的注冊接口的實現(xiàn)方式有很多種,這里介紹其中一種常見的方式。
一般來說,注冊接口需要進行數(shù)據(jù)庫的基本操作,而且是前后端分離式開發(fā)。總的來說就是首先進行數(shù)據(jù)庫的設(shè)計,然后根據(jù)數(shù)據(jù)庫進行編寫服務(wù)端API接口,接著來到客戶端或移動端,進行登錄與注冊的界面設(shè)計,接收服務(wù)端提供的數(shù)據(jù)并顯示在界面上。
以下是一個簡單的注冊接口實現(xiàn)方式:
- POST請求方式:用戶輸入用戶名和密碼,前端將用戶提交的用戶名和密碼發(fā)送到后端進行驗證。如果驗證通過,后端會將用戶信息存儲在數(shù)據(jù)庫中。同時,后端會將用戶信息返回給前端,前端將用戶信息存儲在本地。之后,前端每次請求時都會帶上用戶信息,后端會根據(jù)用戶信息來判斷用戶是否已經(jīng)注冊,如果已經(jīng)注冊,則返回用戶信息,否則返回未注冊狀態(tài)。
如何防止SQL注入攻擊?
SQL注入攻擊是一種常見的網(wǎng)絡(luò)攻擊方式,它可以通過惡意的SQL語句來篡改數(shù)據(jù)庫或者獲取敏感信息。以下是一些防止SQL注入攻擊的方法:
-
使用參數(shù)化查詢:使用參數(shù)化查詢可以將用戶輸入的數(shù)據(jù)與SQL語句分離,從而避免了SQL注入攻擊。在Java中,可以使用PreparedStatement類來實現(xiàn)參數(shù)化查詢。
-
過濾用戶輸入:在用戶輸入數(shù)據(jù)之前,對數(shù)據(jù)進行過濾和驗證,確保數(shù)據(jù)的合法性和安全性。例如,可以使用正則表達式來限制用戶輸入的字符集。
-
使用ORM框架:ORM框架可以自動將用戶輸入的數(shù)據(jù)轉(zhuǎn)換為SQL語句,從而避免了手動編寫SQL語句的風(fēng)險。例如,Hibernate和MyBatis都是常用的ORM框架。
-
限制數(shù)據(jù)庫用戶權(quán)限:將數(shù)據(jù)庫用戶的權(quán)限限制在最小范圍內(nèi),只允許其執(zhí)行必要的操作,可以減少SQL注入攻擊的危害。
-
使用存儲過程:存儲過程可以將SQL語句封裝在一個過程中,從而避免了手動編寫SQL語句的風(fēng)險。此外,存儲過程還可以提高SQL語句的執(zhí)行效率。