【AI编程】Java程序员如何用Cursor 3小时搞定CAS单点登录前端集成

作者:后端小肥肠

🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案

🍊 有疑问可私信或评论区联系我。

🥑 创作不易未经允许严禁转载。

后端集成CAS单点登录:

【Spring Security系列】10分钟实现 SpringSecurity + CAS 完美单点登录方案_spring-security-cas-CSDN博客

1. 前言

当我在GitHub上看到那个刺眼的Issue------CAS前端集成谁来接?,突然意识到:在云原生和低代码的冲击下,单维度技术栈的生存空间正在急速收缩。作为Java程序员,我曾自豪于Spring生态的精通,却不得不在跨域请求和Cookie存储的迷雾中手足无措。

这种困境想必很多后端开发者都曾遇到:

  • 前端同事请假了,产品经理却要求本周上线
  • 跨域问题排查到凌晨,却发现是前端Cookie配置问题
  • 明明是个小需求,却因为前后端分离变得异常棘手

但这也正是机遇所在:

🔑 用AI工具突破技术边界,一个人就是一个全栈团队

🚀 告别"我 只会后端"的局限 ,拥抱全栈开发的 未来

💡 在技术转型的浪潮中抢占先机,提升个人竞争力

本文将展示如何用Cursor这把技术杠杆

  • 无需系统学习前端技术栈(HTML+CSS+JS、Vue等),轻松完成CAS前端集成
  • 获得"前后端通吃"的全局技术视野
  • 掌握AI辅助编程的实战经验

话不多说,让我们开始这段打破技术边界的旅程...

2. CAS单点登录流程梳理(全栈角度)

CAS单点登录流程一共可以分为三大步骤:

  1. 初始访问流程

当用户首次访问前端应用时(假设url为:http://localhost:8080/onemap),前端会自动发起一个API请求到后端服务。由于用户未登录,这个请求会被 Spring Security 的配置类(SecurityConfig )拦截。接着,认证入口点(AuthenticationEntryPointImpl)会返回401未授权状态码,并在响应头中携带CAS登录地址。前端的 axios 请求拦截器检测到401响应后,会自动将页面重定向到CAS统一认证登录页面,引导用户进行登录。

这就像是一个前台接待员(前端)帮访客(用户)问后台保安(后端)能否进入,保安发现访客没有通行证(未登录),就告诉前台让访客去登记处(CAS)办理通行证。

  1. CAS登录认证流程

当用户在CAS统一认证系统中输入用户名和密码后,CAS服务器会对这些凭证进行验证。验证通过后,CAS服务器会生成一个一次性的服务票据(Service Ticket ,简称ST )。然后,CAS服务器会将用户的浏览器重定向回我们的前端应用系统,同时在URL中附带上这个ST票据(例如:http://localhost:8080/onemap/#/login/cas?ticket=ST-xxx)。

这个过程就像是用户在统一认证中心获得了一张临时通行证,然后被引导回我们的系统入口。

  1. Ticket验证流程

当CAS服务器将用户重定向回前端系统后,前端路由会将请求引导至专门处理CAS登录的组件(CasLogin )。该组件首先从URL中解析出CAS服务器颁发的票据(ticket )。然后,组件会调用后端的验证接口( /login/cas )并携带这个ticket。后端的CAS认证过滤器(CasAuthenticationFilter )会处理这个验证请求,验证ticket的有效性。如果验证通过,后端会创建会话并返回会话标识(JSESSIONID)给前端。最后,前端在确认登录成功后,会自动跳转到系统首页。

这个过程就像是用户拿着临时通行证(ticket)到前台(前端)登记,前台让保安(后端)验证通行证,验证通过后给用户发放正式通行证(JSESSIONID),然后引导用户进入大厅(首页)。

3. AI编程

3.1. AI编程前置工作

在使用AI进行编程之前,我们需要做好充分的准备工作。这个过程可以分为三个关键步骤:

  1. 需求分析与技术储备
  • 深入理解系统功能和业务流程

  • 掌握相关技术栈的基础知识

  • 明确项目的技术边界和实现目标

  1. 前期流程梳理
  • 详细梳理技术流程,以本文为例,需要在前期梳理CAS单点登录认证流程

  • 设计数据流转和状态管理方案

  1. 技术基础要求

虽然我们使用AI来协助开发,但仍需要了解相关基础知识(注意这里只是了解,不是让你花费几个月去拼命学),以本文为例,我们需要了解:

  • 前端基础:HTML、CSS、JavaScript

  • Vue.js基础概念:组件、生命周期、路由

  • 开发环境:Node.js、NPM包管理

  • 网络知识:HTTP协议、Cookie机制

需要强调的是,AI编程不是技术许愿池 ,而是一个强大的协作工具。它需要开发者具备足够的技术认知来进行需求分析、方案评估和问题排查。在本项目中,虽然我们使用AI实现了基于Vue2的CAS单点登录前端集成,但如果没有前端基础知识的支撑,在调试和问题排查阶段将会举步维艰。 (只是我个人实践观点,你不要用网上那些非技术人员一天用Cursor开发了一个App还上线的例子来杠我,杠就是你对)

3.2. Cursor开发实战

  1. 说出你的需求,你想实现什么,让他给出方案(大概率是偏离的),比如我的需求就是基于后端已有代码,采用Vue2来进行CAS单点登录集成。
  2. 把它给出的方案流程在你自己脑子里过一遍,不行的话需要修订:

AI会根据你提供的思路再给一版方案,我这里提示词没控制好,它直接开始写了,大家写的时候注意控制一下,方案没问题再开始写:

  1. 验证AI写的代码,进入前端目录(AI生成代码的目录),运行npm install安装依赖,之后运行npm run serve,先把代码跑起来看看:

我们再把后台启动一下,访问前端url的时候直接跳转到了CAS登录界面:

输入用户名和密码后,跳转到了首页,接口数据拿到了:

到此,单点登录集成完成了。(其实很多调试步骤没有被列出来,流程梳理也很费时间,这里大家自己实践就知道了)

4. 核心代码

4.1. 后端核心代码

虽然之前的文章(blog.csdn.net/c1821359022...)已经包含详尽的后端代码,但对接到前端还需要改一下,具体修改如下:

  1. 后端认证入口点(这里需要改一下,之前是直接重定向到CAS认证界面了,现在要返回401,由前端来跳转到CAS认证界面)
java 复制代码
@Component
public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
    
    @Value("${cas.server}")
    private String casServerUrl;
    
    @Value("${cas.client}")
    private String casClientUrl;

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response,
                        AuthenticationException authException) throws IOException {
        // 构建CAS登录URL,带上service参数
        String serviceUrl = casClientUrl + "/#/login/cas";
        String casLoginUrl = casServerUrl + "/login?service=" + URLEncoder.encode(serviceUrl, "UTF-8");
        
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setHeader("Location", casLoginUrl);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{"message":"未登录或登录已过期"}");
    }
}
  1. 修改SecurityConfig配置
  • 配置自定义authenticationEntryPoint(AuthenticationEntryPointImpl)
java 复制代码
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
    .httpBasic().disable()
    .csrf().disable()
    .formLogin().disable()
    .logout().disable()
    .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests
                           .antMatchers("/login/cas", "/logout/cas").permitAll()
                           .antMatchers("/error").permitAll()
                           .antMatchers("/swagger-ui.html").permitAll()
                           .antMatchers("/swagger-resources/**").permitAll()
                           .antMatchers("/v2/api-docs").permitAll()
                           .antMatchers("/webjars/**").permitAll()
                           .antMatchers("/doc.html").permitAll()
                           .anyRequest().authenticated())
    .exceptionHandling()
    .authenticationEntryPoint(authenticationEntryPoint)
    .and()
    .addFilter(casAuthenticationFilter())
    .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class)
    .addFilterBefore(casLogoutFilter(), LogoutFilter.class);

    return http.build();
}
  • 修改ServiceProperties配置
java 复制代码
@Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService("http://localhost:8080/onemap/#/login/cas");
        serviceProperties.setAuthenticateAllArtifacts(true);
        return serviceProperties;
    }

setService()设置的URL就是CAS服务器回调的地址,会带上ticket参数,我们需要将其改为前端地址(我的前端地址为http://localhost:8080/onemap)。

  • 修改CasAuthenticationFilter
java 复制代码
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
    CasAuthenticationFilter filter = new CasAuthenticationFilter();
    
    // 1. 设置认证管理器
    filter.setAuthenticationManager(authenticationManager());
    
    // 2. 设置处理ticket验证的URL路径
    filter.setFilterProcessesUrl("/login/cas");
    
    // 3. 设置service配置
    filter.setServiceProperties(serviceProperties());
    
    // 4. 认证成功处理器
    filter.setAuthenticationSuccessHandler((request, response, authentication) -> {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_OK);
        response.getWriter().write("{"status":"200","message":"登录成功"}");
    });

    // 5. 认证失败处理器
    filter.setAuthenticationFailureHandler((request, response, exception) -> {
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setHeader("Location", casServerUrl + "/login");
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{"message":"认证失败"}");
    });

    return filter;
}

CAS认证过滤器(CasAuthenticationFilter ),用于处理CAS服务器回调时的ticket 验证。它设置了认证管理器来处理认证逻辑,指定/login/cas作为处理ticket验证的URL路径,并注入service配置来指定CAS回调地址。同时配置了两个关键的处理器:认证成功时返回200状态码和成功消息,并自动设置JSESSIONID;认证失败时返回401状态码,并在响应头中设置CAS登录地址以便前端重新发起登录。

4.2. 前端核心代码

  1. 前端拦截请求器
js 复制代码
// utils/request.js
service.interceptors.response.use(
  response => response,
  error => {
    if (error.response?.status === 401) {
      window.location.href = error.response.headers.location;
      return;
    }
    Message.error(error.message);
    return Promise.reject(error);
  }
)

这段代码是前端的axios响应拦截器配置,主要用于统一处理后端接口响应。当接口请求成功时直接返回响应数据;当请求失败时,会检查是否是401未授权错误(表示用户未登录),如果是401则从响应头中获取CAS登录地址并进行页面跳转,否则显示错误消息并将Promise 设为rejected状态。

  1. 前端CAS回调处理
js 复制代码
// views/login/CasLogin.vue
export default {
  methods: {
    getTicketFromUrl() {
      const url = window.location.href;
      const hashIndex = url.indexOf('#');
      const queryString = hashIndex > -1 ? url.substring(0, hashIndex) : url;
      const urlParams = new URLSearchParams(queryString.split('?')[1]);
      return urlParams.get('ticket');
    },
    async handleLogin() {
      try {
        const ticket = this.getTicketFromUrl();
        const response = await validateTicket(ticket);
        if (response.status === 200) {
          this.$router.push('/');
        }
      } catch (error) {
        this.error = error.message;
      }
    }
  }
}

这段代码是CAS登录回调处理组件的核心方法,主要完成两个任务:getTicketFromUrl 方法负责从URL中解析CAS服务器回调时携带的ticket参数(处理类似http://localhost:8080/onemap/#/login/cas?ticket=ST-xxx 这样的URL);handleLogin方法则负责调用后端接口验证这个ticket的有效性,如果验证成功(返回200状态码)就跳转到系统首页,验证失败则显示错误信息。

5. 源码获取

关注gzh后端小肥肠,点击底部【资源】菜单就能获取前端源码,后端源码已经很详尽,不再提供。

6. 结语

这次CAS集成的实战,远不止实现一个功能这么简单。它证明了:在AI工具的加持下,后端程序员完全能驾驭前端关键模块

🎯 技术成长启示

1️⃣ AI不是万能的,但懂AI的程序员是万能的

2️⃣ 技术边界正在消失,全栈思维是必备技能

3️⃣学会用AI工具,让你的能力突破天际

📚你的下一步行动:

1️⃣ 立即下载源码

2️⃣ 参考往期《【Spring Security系列】10分钟实现 SpringSecurity + CAS 完美单点登录方案》,构建高可用认证体系

3️⃣ 安装Cursor,用我的方法尝试一下AI编程(你会回来谢我)

如果本文对你有帮助,请动动你发财的小手点点关注,小肥肠将持续分享更多AI干货文章~

相关推荐
KD2 小时前
设计模式——责任链模式实战,优雅处理Kafka消息
后端·设计模式·kafka
未来之窗软件服务3 小时前
一体化系统(九)智慧社区综合报表——东方仙盟练气期
大数据·前端·仙盟创梦ide·东方仙盟·东方仙盟一体化
陈天伟教授6 小时前
人工智能训练师认证教程(2)Python os入门教程
前端·数据库·python
信看7 小时前
NMEA-GNSS-RTK 定位html小工具
前端·javascript·html
Tony Bai7 小时前
【API 设计之道】04 字段掩码模式:让前端决定后端返回什么
前端
苏打水com7 小时前
第十四篇:Day40-42 前端架构设计入门——从“功能实现”到“架构思维”(对标职场“大型项目架构”需求)
前端·架构
king王一帅7 小时前
流式渲染 Incremark、ant-design-x markdown、streammarkdown-vue 全流程方案对比
前端·javascript·人工智能
苏打水com7 小时前
第十八篇:Day52-54 前端跨端开发进阶——从“多端适配”到“跨端统一”(对标职场“全栈化”需求)
前端
Bigger8 小时前
后端拒写接口?前端硬核自救:纯前端实现静态资源下载全链路解析
前端·浏览器·vite