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

原创网站设计费用中国新闻社

原创网站设计费用,中国新闻社,建筑人才招聘网站平台,上海住房和城乡建设局网站引言:现代Web应用认证的重要性 在当今数字化时代,用户认证是Web应用的基石。无论是电商平台、社交媒体还是企业系统,安全的登录注册功能都至关重要。本文将手把手教你使用Spring Boot作为后端、Angular作为前端,构建一个完整的登…

引言:现代Web应用认证的重要性

在当今数字化时代,用户认证是Web应用的基石。无论是电商平台、社交媒体还是企业系统,安全的登录注册功能都至关重要。本文将手把手教你使用Spring Boot作为后端、Angular作为前端,构建一个完整的登录注册系统。

系统整体架构设计

我们的系统采用经典的前后端分离架构:

graph TDsubgraph Frontend[Angular前端]A[登录组件] -->|调用| B[认证服务]C[注册组件] -->|调用| BD[路由守卫] -->|保护| E[受保护路由]F[HTTP拦截器] -->|添加Token| G[HTTP请求]endsubgraph Backend[Spring Boot后端]H[认证控制器] -->|处理| I[注册端点]H -->|处理| J[登录端点]K[安全配置] -->|保护| L[受保护API]M[JWT工具] -->|生成/验证| N[认证]O[用户仓库] -->|数据操作| P[数据库]endFrontend -->|HTTP API调用| Backend

架构核心组件:

  1. 前端:Angular应用,包含登录/注册组件、认证服务和路由守卫
  2. 后端:Spring Boot应用,提供REST API,处理认证和用户管理
  3. 通信:HTTPS协议,JSON数据格式
  4. 认证:基于JWT(JSON Web Token)的无状态认证机制

后端实现:Spring Boot安全认证

技术栈

  • Spring Security
  • Spring Data JPA
  • JJWT库
  • H2数据库(开发环境)
  • Lombok

关键代码实现

1. 用户实体类
@Entity
@Data
@NoArgsConstructor
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(unique = true)private String email;private String password;private String name;private String role = "USER";private LocalDateTime createdAt = LocalDateTime.now();
}
2. JWT工具类
@Component
public class JwtUtil {private final String SECRET_KEY = "your-strong-secret-key-here";private final long EXPIRATION_MS = 10 * 60 * 60 * 1000; // 10小时public String generateToken(UserDetails userDetails) {return Jwts.builder().setSubject(userDetails.getUsername()).setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_MS)).signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();}public Boolean validateToken(String token, UserDetails userDetails) {final String username = extractUsername(token);return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));}
}
3. 安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsServiceImpl userDetailsService;@Autowiredprivate JwtUtil jwtUtil;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.csrf().disable().authorizeRequests().antMatchers("/api/auth/**", "/h2-console/**").permitAll().anyRequest().authenticated().and().addFilter(new JwtAuthenticationFilter(authenticationManager(), jwtUtil)).sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);// 允许H2控制台的帧访问http.headers().frameOptions().disable();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}
4. 认证控制器
@RestController
@RequestMapping("/api/auth")
public class AuthController {@PostMapping("/register")public ResponseEntity<?> register(@Valid @RequestBody RegisterRequest request) {if (userRepository.existsByEmail(request.getEmail())) {return ResponseEntity.badRequest().body(Map.of("message", "Email already exists"));}User user = new User();user.setEmail(request.getEmail());user.setName(request.getName());user.setPassword(passwordEncoder.encode(request.getPassword()));userRepository.save(user);return ResponseEntity.ok(Map.of("message", "User registered successfully"));}@PostMapping("/login")public ResponseEntity<?> login(@Valid @RequestBody LoginRequest request) {try {Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(request.getEmail(),request.getPassword()));UserDetails userDetails = (UserDetails) authentication.getPrincipal();String jwt = jwtUtil.generateToken(userDetails);return ResponseEntity.ok(new AuthResponse(jwt));} catch (BadCredentialsException e) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(Map.of("message", "Invalid credentials"));}}
}

前端实现:Angular认证系统

项目结构

src/
├── app/
│   ├── core/
│   │   ├── guards/          # 路由守卫
│   │   ├── interceptors/     # HTTP拦截器
│   │   └── services/         # 核心服务
│   ├── modules/
│   │   ├── auth/             # 认证模块
│   │   └── dashboard/        # 主应用模块
│   ├── shared/               # 共享模块
│   ├── app-routing.module.ts # 路由配置
│   └── app.module.ts         # 主模块

关键组件实现

1. 认证服务
@Injectable({ providedIn: 'root' })
export class AuthService {private readonly apiUrl = `${environment.apiUrl}/auth`;private currentUserSubject = new BehaviorSubject<User | null>(null);public currentUser$ = this.currentUserSubject.asObservable();constructor(private http: HttpClient,private tokenService: TokenService,private router: Router) {const user = localStorage.getItem('currentUser');if (user) {this.currentUserSubject.next(JSON.parse(user));}}login(credentials: { email: string; password: string }): Observable<any> {return this.http.post<{ token: string }>(`${this.apiUrl}/login`, credentials).pipe(tap(response => {this.tokenService.setToken(response.token);this.fetchCurrentUser();}));}fetchCurrentUser(): void {this.http.get<User>(`${environment.apiUrl}/users/me`).subscribe({next: user => {this.currentUserSubject.next(user);localStorage.setItem('currentUser', JSON.stringify(user));},error: () => this.logout()});}logout(): void {this.tokenService.removeToken();this.currentUserSubject.next(null);localStorage.removeItem('currentUser');this.router.navigate(['/login']);}
}
2. 登录组件
@Component({selector: 'app-login',templateUrl: './login.component.html',styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {loginForm: FormGroup;isLoading = false;errorMessage: string | null = null;returnUrl: string | null = null;showPassword = false;constructor(private fb: FormBuilder,private authService: AuthService,private router: Router,private route: ActivatedRoute) {this.loginForm = this.fb.group({email: ['', [Validators.required, Validators.email]],password: ['', Validators.required],rememberMe: [false]});}onSubmit(): void {if (this.loginForm.invalid) return;this.isLoading = true;this.errorMessage = null;const { email, password } = this.loginForm.value;this.authService.login({ email, password }).subscribe({next: () => {this.router.navigateByUrl(this.returnUrl || '/dashboard');},error: (err) => {this.errorMessage = '登录失败,请检查您的凭据';this.isLoading = false;}});}
}
3. 登录组件模板
<div class="login-container"><mat-card class="login-card"><mat-card-header><mat-card-title>欢迎回来</mat-card-title><mat-card-subtitle>请登录您的账户</mat-card-subtitle></mat-card-header><mat-card-content><form [formGroup]="loginForm" (ngSubmit)="onSubmit()"><mat-form-field appearance="outline"><mat-label>电子邮箱</mat-label><input matInput formControlName="email" type="email"><mat-icon matSuffix>mail</mat-icon><mat-error *ngIf="loginForm.get('email')?.hasError('required')">邮箱为必填项</mat-error></mat-form-field><mat-form-field appearance="outline"><mat-label>密码</mat-label><input matInput [type]="showPassword ? 'text' : 'password'" formControlName="password"><button type="button" mat-icon-button matSuffix(click)="togglePasswordVisibility()"><mat-icon>{{ showPassword ? 'visibility_off' : 'visibility' }}</mat-icon></button></mat-form-field><button mat-raised-button color="primary" type="submit"[disabled]="loginForm.invalid || isLoading"><span *ngIf="!isLoading">登录</span><mat-spinner *ngIf="isLoading" diameter="20"></mat-spinner></button></form></mat-card-content></mat-card>
</div>
4. HTTP拦截器
@Injectable()
export class AuthInterceptor implements HttpInterceptor {constructor(private tokenService: TokenService,private authService: AuthService,private router: Router) {}intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {const token = this.tokenService.getToken();let authReq = request;if (token) {authReq = request.clone({setHeaders: {Authorization: `Bearer ${token}`}});}return next.handle(authReq).pipe(catchError((error: HttpErrorResponse) => {if (error.status === 401) {this.authService.logout();this.router.navigate(['/login'], { queryParams: { expired: true } });}return throwError(() => error);}));}
}

系统数据流分析

登录流程

UserAngularSpringBootDatabase输入凭据并提交POST /api/auth/login查询用户返回用户数据生成JWT200 OK (含JWT)存储Token跳转到主页401 Unauthorized显示错误alt[认证成功][认证失败]UserAngularSpringBootDatabase

注册流程

UserAngularSpringBootDatabase填写注册表单POST /api/auth/register检查邮箱唯一性密码加密保存用户保存成功200 OK显示成功消息400 Bad Request显示错误alt[邮箱可用][邮箱已存在]UserAngularSpringBootDatabase

安全架构设计

HTTPS
Angular前端
Spring Boot后端
Spring Security
JWT认证
Token生成
Token验证
密码加密
BCrypt
CORS配置
CSRF防护

安全措施:

  1. 密码安全:BCrypt强哈希算法存储密码
  2. 传输安全:强制使用HTTPS
  3. 令牌安全
    • JWT设置合理有效期(建议2小时)
    • 使用强密钥(256位以上)
  4. 跨域控制:严格的白名单策略
  5. 输入验证:前后端双重验证

部署架构

HTTPS
静态文件
API代理
用户
Nginx
Angular应用
Spring Boot应用
MySQL数据库集群

部署要点:

  1. 使用Nginx作为反向代理和静态文件服务器
  2. Spring Boot应用使用内嵌Tomcat
  3. 数据库主从复制提高可用性
  4. 使用环境变量管理敏感信息
  5. 配置监控和日志系统

总结与扩展

我们实现了一个完整的登录注册系统,具有以下特点:

✅ 前后端分离架构
✅ JWT无状态认证
✅ 响应式表单验证
✅ 路由级权限控制
✅ 多层安全防护

扩展方向:

  1. 添加社交登录(OAuth2)
  2. 实现双因素认证
  3. 集成短信/邮箱验证
  4. 添加RBAC权限管理系统
  5. 实现密码重置功能

项目源码
GitHub - Spring Boot后端
GitHub - Angular前端

通过本文,你应该已经掌握了使用Spring Boot和Angular构建登录注册系统的核心知识和技能。这个架构不仅适用于登录注册功能,还可以作为任何需要用户认证的Web应用的基础。

http://www.tdrn.cn/news/101.html

相关文章:

  • 政府 内部 网站中国互联网电视app下载安装
  • 菠菜导航网站可以做排名优化价格
  • 打开b站看直播公众号关键词排名优化
  • 营销型网站建设的标准临沂森佳木业有限公司
  • 家具能在什么网站上做培训学校怎么招生
  • 在工商局网站如果做注销公告中国搜索网站排名
  • 网页设计代码模板源代码达州seo
  • web网站开发需要什么?seo网站推广收费
  • 清远 网站建设网站推广方法
  • 哪个平台可以免费推广seo店铺描述例子
  • 网站google排名出现过几分钟在线排名优化
  • h5直播网站站长之家seo一点询
  • 制作一份网站建设的简要任务执行书网站搜索引擎优化主要方法
  • 国外那些网站是做五金批发今日最新消息
  • 网站制作如何抖音seo源码搭建
  • 英德市建设及城乡管理局网站网络营销常见术语
  • 凡科网站可以做淘宝客吗武汉网站制作
  • 网站模板下载 网盘产品策划方案怎么做
  • 新网站建设特色网络营销专业学校排名
  • wordpress重置query循环郑州seo线上推广系统
  • 网站备案麻烦么百度 人工客服
  • 创建地址怎么弄厦门seo起梦网络科技
  • 衡水网站建设服务搜索引擎营销的主要方法
  • 娄底网站开发1688黄页大全进口
  • apache 做网站济南网站建设
  • 网站公司怎么做运营商易推广
  • 驻马店广告制作公司百度搜索网站优化
  • 互动科技 网站快照网站
  • 建设网站地图素材短链接生成
  • 创业中文网站模板长沙网站优化seo