You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Node.js+MySQL后端,如何在Angular中设置数据库Cookie并显示登录用户名

登录成功后显示用户名及Angular Cookie处理方案(Node.js+MySQL后端)

一、后端(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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:55:37