Spring Security 教程:从入门到精通(含 OAuth2 接入)

Spring Security 教程:从入门到精通(含 OAuth2 接入)

Spring Security 是 Spring 框架中备受推崇的安全模块,广泛应用于构建安全可靠的企业级应用程序。它提供了一套全面的解决方案,涵盖身份认证(Authentication)、授权(Authorization)以及防范各种网络安全威胁(如 CSRF、会话固定攻击等)。本文将带你深入探索 Spring Security,从基础概念到高级特性,最终实现 OAuth2 接入,助力你打造高度安全的 Web 应用。

一、环境准备

在开始学习之前,确保你的开发环境已经准备好以下工具:

Java JDK:版本建议使用 JDK 8 或更高版本。可以通过命令 java -version 来检查已安装的 Java 版本。
构建工具:本文以 Maven 为例,但同样适用于 Gradle。你可以从 Maven 官方网站 下载并安装 Maven,安装完成后,使用命令 mvn -v 验证。
集成开发环境(IDE):如 IntelliJ IDEA 或 Eclipse,能够提高开发效率。

二、Spring Security 基础概念

在深入了解 Spring Security 的配置和用法之前,先理解一些关键概念:

认证(Authentication):验证用户身份的过程,确认用户是否为用户声称的身份。
授权(Authorization):在用户身份经过验证后,确定用户具有执行特定操作或访问特定资源的权限。
安全过滤器链(Security Filter Chain):Spring Security 的核心组件,负责处理认证和授权逻辑,包含多个安全过滤器,按照特定顺序对请求进行处理。
上下文(SecurityContext):存储当前认证用户的信息,可用于在整个请求周期内访问用户相关数据。

三、创建 Spring Boot 项目并引入依赖

  1. 创建 Spring Boot 项目

    使用 Spring Initializr 可以轻松创建一个新的 Spring Boot 项目。在网页上选择以下配置:

    Project:选择 Maven Project 或 Gradle Project。
    Language:选择 Java。
    Spring Boot:选择最新稳定版本。
    Project Metadata:填写 GroupArtifact 等信息。
    Packaging:选择 Jar。
    Java:选择合适的 Java 版本(推荐 8 或更高)。

    1. 添加依赖

    在依赖项中选择 Spring WebSpring Security,点击 “Generate” 下载项目压缩包,解压后导入 IDE 开始开发。

四、Spring Security 入门:自动配置与默认设置

添加 Spring Security 依赖后,Spring Boot 会自动配置一个基本的安全机制。启动应用程序,访问任意路径,Spring Security 都会重定向到你默认的登录页面。默认的用户名是 user,密码在应用启动时会输出到控制台。

默认安全配置解析

默认情况下,Spring Security 使用内存身份验证(In-Memory Authentication),并配置了基本的认证规则。这意味着应用启动时,Spring Security 会自动创建一个内置的用户存储,包含一个用户名为 user,密码为一个随机生成的字符串(输出在控制台)的用户。

五、自定义内存用户认证

为了更好地示范,我们可以自定义内存中的用户认证信息。创建一个配置类继承自 WebSecurityConfigurerAdapter,重写 configure 方法来配置用户信息。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder().encode("admin123")).roles("ADMIN").and().withUser("user").password(passwordEncoder().encode("user123")).roles("USER");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("USER", "ADMIN").anyRequest().authenticated().and().formLogin();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}

详细解释

  1. @EnableWebSecurity:开启 Spring Security 的安全功能。
  2. configure(AuthenticationManagerBuilder auth):配置用户认证信息。
    • 使用 inMemoryAuthentication() 启用内存中用户存储。
    withUser() 方法定义用户,指定用户名、密码(需要先通过密码编码器编码)和角色。
  3. configure(HttpSecurity http):配置 HTTP 请求的安全规则。
    authorizeRequests() 开始请求授权配置。
    antMatchers("/admin/**").hasRole("ADMIN") 表示以 /admin/ 开头的路径需要 ADMIN 角色权限。
    antMatchers("/user/**").hasAnyRole("USER", "ADMIN") 表示以 /user/ 开头的路径需要 USERADMIN 角色权限。
    anyRequest().authenticated() 表示其他所有请求都需要认证。
    formLogin() 启用表单登录方式。
  4. 密码编码器:使用 BCryptPasswordEncoder 对密码进行加密存储,提高安全性。

六、基于数据库的用户认证

在实际应用中,用户信息通常存储在数据库中。以下将以 MySQL 数据库为例,演示如何实现基于数据库的用户认证。

1. 数据库设计

创建用户表(user)和角色表(role)以及关联表(user_role):

CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(100) NOT NULL
);CREATE TABLE role (id BIGINT AUTO_INCREMENT PRIMARY KEY,role_name VARCHAR(50) NOT NULL UNIQUE
);CREATE TABLE user_role (user_id BIGINT NOT NULL,role_id BIGINT NOT NULL,PRIMARY KEY (user_id, role_id),FOREIGN KEY (user_id) REFERENCES user(id),FOREIGN KEY (role_id) REFERENCES role(id)
);

2. 实体类定义

创建 JPA 实体类,表示用户和角色:

import javax.persistence.*;
import java.util.Set;@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@ManyToMany(fetch = FetchType.EAGER)@JoinTable(name = "user_role",joinColumns = @JoinColumn(name = "user_id"),inverseJoinColumns = @JoinColumn(name = "role_id"))private Set<Role> roles;// getters and setters
}@Entity
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String roleName;// getters and setters
}

3. 数据访问层(Repository)

创建 UserRepositoryRoleRepository

import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {User findByUsername(String username);
}public interface RoleRepository extends JpaRepository<Role, Long> {
}

4. 实现 UserDetailsService

UserDetailsService 是 Spring Security 用于加载用户信息的核心接口。我们创建一个自定义的实现类:

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;import java.util.HashSet;
import java.util.Set;@Service
public class CustomUserDetailsService implements UserDetailsService {private final UserRepository userRepository;public CustomUserDetailsService(UserRepository userRepository) {this.userRepository = userRepository;}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {User user = userRepository.findByUsername(username);if (user == null) {throw new UsernameNotFoundException("User not found");}Set<GrantedAuthority> authorities = new HashSet<>();for (Role role : user.getRoles()) {authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getRoleName()));}return new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),authorities);}
}

5. 更新安全配置

SecurityConfig 类中注入 CustomUserDetailsService 并更新认证配置:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(customUserDetailsService).passwordEncoder(passwordEncoder());
}

确保 customUserDetailsService 已经被正确注入到 SecurityConfig 类中。

七、授权管理

Spring Security 提供了灵活的授权机制,允许你基于角色、权限或其他条件来控制资源的访问。

1. 使用注解进行方法级授权

你可以在控制器的方法上使用 @PreAuthorize@PostAuthorize 等注解来定义细粒度的访问控制规则。

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class AdminController {@GetMapping("/admin/dashboard")@PreAuthorize("hasRole('ADMIN')")public String adminDashboard() {return "欢迎来到管理员仪表盘";}
}

2. 在安全配置中定义 URL 级授权

SecurityConfig 类的 configure(HttpSecurity http) 方法中,你可以使用表达式语言(SpEL)来定义基于 URL 的访问规则。

@Override
protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("USER", "ADMIN").anyRequest().authenticated().and().formLogin().loginPage("/login") // 自定义登录页面.permitAll().and().logout().permitAll();
}

3. 自定义权限评估器

对于更复杂的授权需求,你可以实现自定义的 PermissionEvaluator 并将其集成到 Spring Security 中。

八、CSRF 防护

跨站请求伪造(CSRF)是一种常见的网络攻击方式。Spring Security 默认启用了 CSRF 防护机制,它会为每个表单提交生成一个 CSRF 令牌,并在服务器端进行验证。

1. 禁用 CSRF 防护

在某些情况下,如构建 RESTful API 时,你可能需要禁用 CSRF 防护。可以在安全配置中这样做:

@Override
protected void configure(HttpSecurity http) throws Exception {http.csrf().disable()// 其他配置
}

注意:禁用 CSRF 防护会使应用面临风险,建议仅在必要时禁用,并确保其他防护措施到位。

2. 自定义 CSRF 令牌存储

你可以自定义 CSRF 令牌的存储方式,例如将其存储在 HTTP 头中而不是默认的 Cookie 中,以适应特定的应用需求。

九、OAuth2 接入

OAuth2 是一种开放标准,用于授权第三方应用访问用户资源,而无需获取用户的凭证。Spring Security 提供了对 OAuth2 的全面支持,使得集成变得简便。

1. 添加依赖

为了支持 OAuth2 客户端或资源服务器功能,需要在 pom.xml 中添加相应的依赖。

作为 OAuth2 客户端:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>

作为 OAuth2 资源服务器:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>

2. 配置 OAuth2 客户端

假设我们要将应用配置为 OAuth2 客户端,以使用 Google 进行登录。

application.properties 中添加配置:

spring.security.oauth2.client.registration.google.client-id=YOUR_GOOGLE_CLIENT_ID
spring.security.oauth2.client.registration.google.client-secret=YOUR_GOOGLE_CLIENT_SECRET
spring.security.oauth2.client.registration.google.redirect-uri={baseUrl}/login/oauth2/code/{registrationId}
spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/v2/auth
spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token
spring.security.oauth2.client.provider.google.user-info-uri=https://www.googleapis.com/oauth2/v3/userinfo
spring.security.oauth2.client.provider.google.user-name-attribute=sub

更新安全配置类以启用 OAuth2 登录:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
@EnableWebSecurity
public class OAuth2SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorizeRequests ->authorizeRequests.antMatchers("/", "/login**").permitAll().anyRequest().authenticated()).oauth2Login(oauth2Login ->oauth2Login.loginPage("/login"));return http.build();}
}

3. 配置 OAuth2 资源服务器

如果你的应用是一个 OAuth2 资源服务器,需要验证传入请求的访问令牌。

application.properties 中添加配置:

spring.security.oauth2.resourceserver.jwt.issuer-uri=https://accounts.google.com

更新安全配置类以启用资源服务器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
@EnableWebSecurity
public class ResourceServerConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeRequests(authorizeRequests ->authorizeRequests.antMatchers("/", "/public/**").permitAll().anyRequest().authenticated()).oauth2ResourceServer(oauth2ResourceServer ->oauth2ResourceServer.jwt());return http.build();}
}

4. 自定义 OAuth2 登录流程

你可以自定义 OAuth2 登录后的处理逻辑,例如获取额外的用户信息、映射用户角色等。

创建自定义的 OAuth2UserService

import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.stereotype.Service;@Service
public class CustomOAuth2UserService extends DefaultOAuth2UserService {@Overridepublic OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException {OAuth2User user = super.loadUser(userRequest);// 在这里可以添加自定义逻辑,如映射角色、获取额外信息等return user;}
}

在安全配置中注入自定义的 OAuth2UserService

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, CustomOAuth2UserService customOAuth2UserService) throws Exception {http.authorizeRequests(authorizeRequests ->authorizeRequests.antMatchers("/", "/login**").permitAll().anyRequest().authenticated()).oauth2Login(oauth2Login ->oauth2Login.userInfoEndpoint(userInfoEndpoint ->userInfoEndpoint.userService(customOAuth2UserService)));return http.build();
}

十、高级特性与优化

1. 使用 JWT(JSON Web Token)

JWT 是一种紧凑且自包含的令牌格式,常用于无状态的认证机制。Spring Security 支持 JWT 的生成与验证,适用于构建微服务架构中的认证与授权。

2. 多因素认证(MFA)

为了提高安全性,可以集成多因素认证,如短信验证码、TOTP(基于时间的一次性密码)等。Spring Security 可以与第三方库或服务集成实现 MFA。

3. 细粒度权限控制

通过自定义权限评估器、访问决策管理器等组件,可以实现更细粒度的权限控制,满足复杂业务场景下的安全需求。

4. 安全审计与日志

记录用户的认证与授权活动,有助于监控潜在的安全威胁和进行事后审计。可以集成日志框架(如 Logback、Log4j2)与安全事件监听器来实现。

十一、总结

Spring Security 提供了一个强大而灵活的安全框架,涵盖了从基础认证到高级授权的各个方面。通过本文的学习,你应该已经掌握了:

  1. Spring Security 的基本概念和入门配置。
  2. 如何实现基于内存和数据库的用户认证。
  3. 授权管理的多种方式,包括方法级和 URL 级授权。
  4. CSRF 防护机制及其配置。
  5. 如何集成 OAuth2 实现第三方登录和资源保护。
  6. 一些高级特性和优化方法,提升应用的安全性。

Spring Security 功能丰富,适用于各种复杂的应用场景。建议在实际项目中,根据具体需求深入学习和实践相关内容,并参考 Spring Security 官方文档 获取最新的信息和最佳实践。

希望这个全面的教程能够帮助你从入门到精通掌握 Spring Security,并成功应用于你的项目中,构建安全可靠的 Web 应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72518.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL ES 入门指南:从基础到实战

引言&#xff1a;为什么需要 OpenGL ES&#xff1f; 在当今的嵌入式设备&#xff08;如智能手机、汽车仪表盘、智能家居中控屏&#xff09;中&#xff0c;流畅的图形渲染能力是用户体验的核心。OpenGL ES&#xff08;OpenGL for Embedded Systems&#xff09; 作为行业标准&am…

java的WeakHashMap可以用来做缓存使用?强软弱虚四种引用对比

在 Java 中&#xff0c;引用&#xff08;Reference&#xff09;机制用于管理对象的生命周期和垃圾回收。Java 提供了四种类型的引用&#xff1a;强引用&#xff08;Strong Reference&#xff09;、软引用&#xff08;Soft Reference&#xff09;、弱引用&#xff08;Weak Refer…

51单片机指令系统入门

目录 基本概念讲解 一、机器指令​ 二、汇编指令​ &#xff08;一&#xff09;汇编指令的一般格式 &#xff08;二&#xff09;按字节数分类的指令 三、高级指令 总结​ 基本概念讲解 指令是计算机&#xff08;或单片机&#xff09;中 CPU 能够识别并执行的基本操作命令…

使用 Docker 部署 MySQL 8

使用 Docker 部署 MySQL 8 详细指南 MySQL 是一个广泛使用的开源关系型数据库管理系统。通过 Docker 部署 MySQL 8 可以快速搭建一个可移植、可扩展的数据库环境。本文将详细介绍如何使用 Docker 部署 MySQL 8&#xff0c;并讲解如何根据需求配置 MySQL。 从拉取镜像开始的详细…

AtCoder Beginner Contest 397(ABCDE)

目录 A - Thermometer 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; B - Ticket Gate Log 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; C - Variety Split Easy 翻译&#xff1a; 思路&#xff1a; 实现&#xff1a; D - Cubes 翻译&#xff1a…

数模AI使用教程(新) 2025.3.17

DeepseekR1doubao1.5大模型组合&#xff0c;数模智能体题目解答一等水平&#xff0c;另外也有统计建模、期刊复现智能体。 功能&#xff1a;问题重述、解释数据文件、深度思考与逻辑梳理、问题关键点分析、知识整理、查找数据源、问题分析、使用方法推荐[会询问要求]、模型建立…

Spring Cloud Gateway 生产级实践:高可用 API 网关架构与流量治理解析

API 网关的核心价值 在分布式微服务架构中&#xff0c;API 网关作为系统流量的唯一入口&#xff0c;承担着路由分发、安全防护、流量治理三大核心职责。Spring Cloud Gateway 基于响应式编程模型与 Netty 高性能网络框架&#xff0c;提供灵活的路由规则、动态过滤器链和深度集…

在Pycharm配置conda虚拟环境的Python解释器

〇、前言 今天在配置python解释器时遇到了这样的问题 经过一下午自行摸索、上网搜寻后&#xff0c;终于找到的解决的方案&#xff0c;遂将该方法简要的记录下来&#xff0c;以备后用&#xff0c;并希望能帮助到有同样问题或需求的朋友:) 我所使用的软件的版本如下&#xff0c;假…

宽带(Broadband)

宽带&#xff08;Broadband&#xff09; 是一种高速互联网接入技术&#xff0c;能够同时传输多种类型的数据&#xff08;如语音、视频、文本等&#xff09;。与传统的窄带&#xff08;如拨号上网&#xff09;相比&#xff0c;宽带提供了更高的数据传输速率和更稳定的连接&#…

集成学习(上):Bagging集成方法

一、什么是集成学习&#xff1f; 在机器学习的世界里&#xff0c;没有哪个模型是完美无缺的。就像古希腊神话中的"盲人摸象"&#xff0c;单个模型往往只能捕捉到数据特征的某个侧面。但当我们把多个模型的智慧集合起来&#xff0c;就能像拼图一样还原出完整的真相&a…

VLLM:虚拟大型语言模型(Virtual Large Language Model)

VLLM&#xff1a;虚拟大型语言模型&#xff08;Virtual Large Language Model&#xff09; VLLM指的是一种基于云计算的大型语言模型的虚拟实现。它通常是指那些由多个服务器组成的分布式计算环境中的复杂机器学习模型&#xff0c;这些模型能够处理和理解大量的文本数据。VLLM的…

Springboot+Vue登录、注册功能(含验证码)(后端!)

我们首先写一个接口&#xff0c;叫login&#xff01;然后对传入一个user&#xff0c;因为我们前端肯定是要传过来一个user&#xff0c;然后我们后端返回一个user&#xff0c;因为我们要根据这个去校验&#xff01;我们还引入了一个hutool的一个东西&#xff0c;在pom文件里面引…

冯 • 诺依曼体系结构

冯 • 诺依曼体系结构 一、冯 • 诺依曼体系结构推导阶段 1&#xff1a;初始计算机体系结构&#xff08;仅输入、运算、输出&#xff09;阶段 2&#xff1a;加入控制功能&#xff0c;初步形成 CPU 概念阶段 3&#xff1a;性能瓶颈与引入内存阶段 4&#xff1a;最终冯诺依曼体系…

Python print() 打印多个变量时,可变对象和不可变对象的区别

先来看这段代码&#xff1a; tmp [] print(tmp, tmp.append(1), tmp)输出&#xff1a; [1] None [1]并不是一些人认为的 [] None [1] 这是因为列表是可变对象&#xff0c;print()打印前会先计算出所有结果&#xff0c;最后再打印出来&#xff0c;中间在列表中添加了1&#…

【数学 线性代数】差分约束

前言 C算法与数据结构 本博文代码打包下载 什么是差分约束 x系列是变量&#xff0c;y系列是常量&#xff0c;差分系统由若干如下不等式组成。 x1-x2 < y1 x2-x3 < y2 ⋯ \cdots ⋯ 可能有负环的最短路 个人习惯&#xff1a;如果存在a指向b的边&#xff0c;则a是b的…

AutoGen :使用 Swarm 构建自治型多智能体团队

👉👉👉本人承接各类AI相关应用开发项目(包括但不限于大模型微调、RAG、AI智能体、NLP、机器学习算法、运筹优化算法、数据分析EDA等) !!!👉👉👉 有意愿请私信!!!AutoGen 的 AgentChat 模块提供了一种强大的方法来构建多智能体协作系统。 在之前的文章中,我们探讨了…

2025人工智能“落地生花”:这六大领域正掀起颠覆性革命

——从医疗到养老&#xff0c;一场“AI”的全民狂欢正在上演 2025年的春天&#xff0c;全球科技界的热搜被一个中国AI大模型“霸榜”——DeepSeek。从春晚的机器人热舞到政务系统的“数字员工上岗”&#xff0c;从医疗诊断到工业炼钢&#xff0c;这场始于春节的技术海啸&#…

第27周JavaSpringboot git初识

Git 课程笔记 一、Git 的介绍 1. Git 的诞生背景 Git 是 Linux 内核的作者 Linus Torvalds 为了更好地管理 Linux 内核开发而创建的版本控制系统。在 Linux 内核开发初期&#xff0c;由于开发者众多&#xff0c;协作成本很高&#xff0c;后来使用了 BitKeeper 工具来辅助协作…

蓝耘智算|从静态到动态:探索Maas平台海螺AI图片生成视频功能的强大能力

文章目录 &#x1f44f;一、技术介绍&#x1f44f;二、平台注册&#x1f44f;三、功能体验&#x1f44f;四、总结 随着人工智能技术的快速发展&#xff0c;视频处理和生成技术已经成为了众多行业关注的热点。最近&#xff0c;我有机会体验了蓝耘智算平台的Maas平海螺AI视频产品…

解决从deepseek接口获取的流式响应输出到前端都是undefined的问题

你的前端 EventSource 代码遇到了 undefined 连续输出 的问题&#xff0c;通常是因为&#xff1a; AI 返回的内容被拆成了单个字符&#xff0c;导致前端 JSON.parse(event.data).content 获取到的是单个字符&#xff0c;而 undefined 可能是因为某些数据块没有 content 字段。…