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

适配AWS架构的Angular 4/5认证与Token最佳实践选型咨询

JWT Authentication: The Best Fit for Your Angular + AWS Stack

Hey Nicolò, let’s break this down for your specific setup—Angular on S3, PHP backend on EC2, and Postgres on RDS. After looking at your stack, JSON Web Tokens (JWT) is the most straightforward, efficient choice for token-based authentication here. It’s stateless, plays nicely with both Angular and PHP, and fits perfectly with AWS’s scalable architecture. Let’s walk through a clean implementation step by step.

Why JWT?

  • Stateless: No need to store session data on your EC2 instances, which makes scaling easier if you ever add more servers.
  • Lightweight: Tokens are compact and carry all necessary user info, reducing redundant database calls.
  • CORS-Friendly: Your Angular app on S3 is a static site with a different domain than your EC2 backend—JWT works seamlessly across cross-origin requests.
  • Flexible: Easy to extend later (e.g., integrate with AWS Cognito if you want managed auth down the line).

Step 1: Angular Frontend Implementation

First, we’ll set up your Angular app to handle login, store the token, and attach it to every API request.

1.1 Install Dependencies

While you can handle tokens manually, the @auth0/angular-jwt library simplifies token management:

npm install @auth0/angular-jwt

1.2 Build the Login Component

Create a login form that sends credentials to your PHP backend and stores the received token:

// login.component.ts
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';

@Component({
  selector: 'app-login',
  template: `
    <input type="text" [(ngModel)]="username" placeholder="Username">
    <input type="password" [(ngModel)]="password" placeholder="Password">
    <button (click)="login()">Login</button>
  `
})
export class LoginComponent {
  username: string = '';
  password: string = '';

  constructor(private http: HttpClient, private router: Router) {}

  login() {
    this.http.post('https://your-ec2-domain/login.php', {
      username: this.username,
      password: this.password
    }).subscribe((response: any) => {
      localStorage.setItem('authToken', response.jwt);
      this.router.navigate(['/dashboard']);
    }, error => {
      alert('Invalid credentials');
    });
  }
}

1.3 Add an HTTP Interceptor

Automatically attach the token to every outgoing API request using an interceptor:

// auth.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    const token = localStorage.getItem('authToken');
    if (token) {
      request = request.clone({
        setHeaders: {
          Authorization: `Bearer ${token}`
        }
      });
    }
    return next.handle(request);
  }
}

Register the interceptor in app.module.ts:

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';

@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
  ]
})
export class AppModule {}

Step 2: PHP Backend Implementation

Now we’ll set up your EC2 PHP scripts to validate credentials, generate JWTs, and protect API endpoints.

2.1 Install the JWT Library

Use Composer to install Firebase’s reliable JWT package:

composer require firebase/php-jwt

2.2 Create a Login Endpoint

This script validates user credentials against your Postgres DB and returns a JWT:

// login.php
<?php
require 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

// Configure CORS (restrict to your S3 domain in production!)
header("Access-Control-Allow-Origin: https://your-s3-bucket-domain");
header("Access-Control-Allow-Methods: POST");
header("Content-Type: application/json");

// Connect to Postgres (use PDO for safety)
$db = new PDO(
  'pgsql:host=your-rds-endpoint;dbname=your-db-name;port=5432',
  'your-db-user',
  'your-db-password'
);

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  $data = json_decode(file_get_contents("php://input"));
  
  // Validate input
  if (!isset($data->username) || !isset($data->password)) {
    http_response_code(400);
    echo json_encode(["message" => "Missing username or password"]);
    exit;
  }

  // Fetch user (use parameter binding to prevent SQL injection!)
  $stmt = $db->prepare("SELECT id, username, password_hash FROM users WHERE username = ?");
  $stmt->execute([$data->username]);
  $user = $stmt->fetch(PDO::FETCH_ASSOC);

  // Verify password hash
  if ($user && password_verify($data->password, $user['password_hash'])) {
    // Use a secret key stored in AWS Secrets Manager in production!
    $secret_key = 'your-strong-secret-key';
    $payload = [
      "iss" => "https://your-ec2-domain", // Issuer (your backend)
      "aud" => "https://your-s3-bucket-domain", // Audience (your frontend)
      "iat" => time(), // Issued at
      "exp" => time() + 3600, // Expires in 1 hour
      "user" => [
        "id" => $user['id'],
        "username" => $user['username']
      ]
    ];

    $jwt = JWT::encode($payload, $secret_key, 'HS256');
    echo json_encode([
      "message" => "Login successful",
      "jwt" => $jwt,
      "expires_at" => $payload['exp']
    ]);
  } else {
    http_response_code(401);
    echo json_encode(["message" => "Invalid credentials"]);
  }
}
?>

2.3 Create an Auth Middleware

Protect your API endpoints with a reusable middleware that validates incoming JWTs:

// auth-middleware.php
<?php
require 'vendor/autoload.php';
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

$secret_key = 'your-strong-secret-key';

// Check for Authorization header
$headers = getallheaders();
if (!isset($headers['Authorization']) || !str_starts_with($headers['Authorization'], 'Bearer ')) {
  http_response_code(401);
  echo json_encode(["message" => "Authorization header missing or invalid"]);
  exit;
}

$token = str_replace('Bearer ', '', $headers['Authorization']);

try {
  $decoded = JWT::decode($token, new Key($secret_key, 'HS256'));
  // Make user data available to the protected endpoint
  $GLOBALS['auth_user'] = $decoded->user;
} catch (Exception $e) {
  http_response_code(401);
  echo json_encode([
    "message" => "Invalid or expired token",
    "error" => $e->getMessage()
  ]);
  exit;
}
?>

To protect an endpoint, just include the middleware at the top:

// protected-api.php
<?php
require 'auth-middleware.php';

// Access authenticated user data
$user = $GLOBALS['auth_user'];
echo json_encode(["message" => "Hello, " . $user->username . "!", "user_id" => $user->id]);
?>

Production Best Practices

  • Secure Your Secret Key: Never hardcode it! Store it in AWS Secrets Manager and fetch it in your PHP scripts using the AWS SDK for PHP.
  • Enforce HTTPS: Use AWS CloudFront with SSL for your S3 bucket, and attach an SSL certificate from AWS Certificate Manager to your EC2 instance or load balancer.
  • Token Refresh: Implement a refresh token endpoint to let users get a new JWT without re-logging in when their token expires.
  • Restrict CORS: Replace the wildcard * in your CORS headers with your actual S3 bucket domain to prevent unauthorized cross-origin requests.

内容的提问来源于stack exchange,提问作者Nicolò Scapin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:55:16