基于Node.js+MySQL后端,如何在Angular中设置数据库Cookie并显示登录用户名
一、后端(Node.js+MySQL)实现逻辑
1. 核心流程
- 接收前端登录请求,验证用户账号密码(密码需加密存储)
- 验证通过后,设置Cookie(推荐HttpOnly类型,提升安全性)
- 返回用户基础信息(如用户名)给前端,用于直接显示
2. 代码示例
const express = require('express'); const mysql = require('mysql2'); const bcrypt = require('bcrypt'); const cookieParser = require('cookie-parser'); const app = express(); app.use(express.json()); app.use(cookieParser()); app.use((req, res, next) => { // 跨域配置,允许携带Cookie res.header('Access-Control-Allow-Origin', 'http://localhost:4200'); res.header('Access-Control-Allow-Credentials', 'true'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }); // MySQL连接配置 const db = mysql.createConnection({ host: 'localhost', user: 'root', password: 'your_db_password', database: 'your_db_name' }); // 登录接口 app.post('/api/login', async (req, res) => { const { email, password } = req.body; // 查询用户信息 db.query('SELECT id, username, password FROM users WHERE email = ?', [email], async (err, results) => { if (err) return res.status(500).json({ error: '数据库查询失败' }); if (results.length === 0) return res.status(401).json({ error: '用户不存在' }); const user = results[0]; // 验证密码(需提前用bcrypt.hash加密存储) const passwordMatch = await bcrypt.compare(password, user.password); if (!passwordMatch) return res.status(401).json({ error: '密码错误' }); // 设置HttpOnly Cookie(生产环境需开启secure属性) res.cookie('auth_token', 'your_generated_token', { httpOnly: true, secure: process.env.NODE_ENV === 'production', maxAge: 24 * 60 * 60 * 1000, // 有效期1天 sameSite: 'strict' }); // 返回用户名给前端 res.status(200).json({ success: true, user: { id: user.id, username: user.username } }); }); }); app.listen(3000, () => console.log('后端服务运行于3000端口'));
二、前端Angular实现步骤
1. 登录服务(AuthService)
封装登录请求,管理用户状态,处理Cookie读取:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class AuthService { private currentUser$ = new BehaviorSubject<any>(null); constructor(private http: HttpClient) { // 初始化时从Cookie或localStorage读取用户信息 this.initCurrentUser(); } get currentUser(): Observable<any> { return this.currentUser$.asObservable(); } login(email: string, password: string): Observable<any> { // 发送请求时携带Cookie return this.http.post('/api/login', { email, password }, { withCredentials: true }); } setCurrentUser(user: any): void { this.currentUser$.next(user); // 可选:将用户信息存到localStorage,页面刷新后恢复 localStorage.setItem('currentUser', JSON.stringify(user)); } private initCurrentUser(): void { const savedUser = localStorage.getItem('currentUser'); if (savedUser) { this.currentUser$.next(JSON.parse(savedUser)); } } logout(): void { this.currentUser$.next(null); localStorage.removeItem('currentUser'); // 清除Cookie document.cookie = 'auth_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; } }
2. 登录组件(LoginComponent)
处理表单提交,完成登录逻辑:
import { Component } from '@angular/core'; import { AuthService } from './auth.service'; import { Router } from '@angular/router'; @Component({ selector: 'app-login', template: ` <div class="login-form"> <input type="email" [(ngModel)]="email" name="email" placeholder="邮箱" required> <input type="password" [(ngModel)]="password" name="password" placeholder="密码" required> <button (click)="handleLogin()">登录</button> </div> ` }) export class LoginComponent { email = ''; password = ''; constructor(private authService: AuthService, private router: Router) {} handleLogin(): void { this.authService.login(this.email, this.password).subscribe({ next: (res) => { this.authService.setCurrentUser(res.user); this.router.navigate(['/home']); }, error: (err) => { alert(err.error.error || '登录失败'); } }); } }
3. 页面显示用户名
在任意需要显示用户名的组件(如Header)中订阅用户状态:
import { Component } from '@angular/core'; import { AuthService } from './auth.service'; @Component({ selector: 'app-header', template: ` <div class="header"> <span *ngIf="currentUser">欢迎回来, {{ currentUser.username }}!</span> <button *ngIf="currentUser" (click)="authService.logout()">退出登录</button> </div> ` }) export class HeaderComponent { currentUser: any; constructor(public authService: AuthService) { this.authService.currentUser.subscribe(user => { this.currentUser = user; }); } }
三、关键注意事项
- Cookie安全:后端设置
HttpOnly属性可防止XSS攻击,生产环境必须开启secure(仅HTTPS传输)和SameSite属性 - 密码加密:后端必须用bcrypt等哈希算法存储密码,禁止明文存储
- 跨域配置:后端需开启
Access-Control-Allow-Credentials: true,前端请求需添加withCredentials: true才能携带Cookie - 状态持久化:用
localStorage辅助存储用户信息,避免页面刷新后丢失状态
内容的提问来源于stack exchange,提问作者Jay Mervana
相关产品推荐
相关产品推荐

