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

如何用Java+Hibernate+RESTful API实现AngularJs登录页Oracle身份认证

好的,我来一步步帮你实现这个登录验证流程——从后端Java+Hibernate操作Oracle数据库,到前端AngularJS对接REST API,每个环节都给你具体的代码示例和关键注意事项,确保你能顺利跑通整个流程。

实现步骤分解

1. 后端环境与依赖配置(Spring Boot + Hibernate + Oracle)

我们用Spring Boot快速搭建REST服务,它已经封装了Hibernate的核心功能(通过Spring Data JPA),搭配Oracle数据库。首先在Maven的pom.xml中添加必要依赖:

<!-- Spring Web:用于构建REST接口 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA:封装Hibernate,简化数据库操作 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Oracle JDBC驱动:连接Oracle数据库 -->
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- BCrypt密码加密:安全存储用户密码 -->
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-crypto</artifactId>
</dependency>

然后在application.properties中配置Oracle数据库连接和Hibernate参数:

# 数据库连接配置
spring.datasource.url=jdbc:oracle:thin:@//你的Oracle地址:端口/服务名
spring.datasource.username=你的数据库用户名
spring.datasource.password=你的数据库密码

# Hibernate配置
spring.jpa.hibernate.ddl-auto=update # 根据实体类自动更新表结构(生产环境建议用none)
spring.jpa.show-sql=true # 显示SQL语句(调试用)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle12cDialect

2. 数据库实体类(User Entity)

创建对应Oracle用户表的实体类,假设你的表名为USERS,包含id、username、password、email字段:

import jakarta.persistence.*;
import lombok.Data;

@Entity
@Table(name = "USERS")
@Data // Lombok注解,自动生成getter/setter,简化代码
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
    @SequenceGenerator(name = "user_seq", sequenceName = "USERS_SEQ", allocationSize = 1)
    private Long id;

    @Column(name = "USERNAME", unique = true, nullable = false, length = 50)
    private String username;

    @Column(name = "PASSWORD", nullable = false, length = 255)
    private String password;

    @Column(name = "EMAIL", unique = true, length = 100)
    private String email;
}

3. 数据访问层(User Repository)

用Spring Data JPA定义Repository接口,自动实现数据库查询逻辑:

import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;

public interface UserRepository extends JpaRepository<User, Long> {
    // 根据用户名查询用户,返回Optional避免空指针异常
    Optional<User> findByUsername(String username);
}

4. 业务逻辑层(Auth Service)

编写登录验证的核心逻辑,重点处理密码加密验证(绝对不要明文存储密码):

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;

@Service
public class AuthService {
    private final UserRepository userRepository;
    private final BCryptPasswordEncoder passwordEncoder;

    // 构造函数注入(Spring 4.3+无需@Autowired)
    public AuthService(UserRepository userRepository, BCryptPasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }

    public boolean validateCredentials(String username, String rawPassword) {
        Optional<User> userOpt = userRepository.findByUsername(username);
        if (userOpt.isEmpty()) {
            return false; // 用户不存在
        }
        User user = userOpt.get();
        // 验证明文密码与数据库中加密后的密码是否匹配
        return passwordEncoder.matches(rawPassword, user.getPassword());
    }

    // 注册用户时的密码加密方法(如果需要实现注册功能)
    public User registerUser(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        return userRepository.save(user);
    }
}

还要配置BCrypt加密器的Bean:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

@Configuration
public class SecurityConfig {
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

5. REST API控制器(Auth Controller)

编写接收前端登录请求的REST接口,并处理跨域问题(如果前后端部署在不同端口/域名):

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:8081") // 替换为你的AngularJS前端域名/端口
public class AuthController {
    private final AuthService authService;

    public AuthController(AuthService authService) {
        this.authService = authService;
    }

    // 登录请求参数DTO
    public static class LoginRequest {
        private String username;
        private String password;
        
        // getter和setter
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
    }

    // 登录响应DTO
    public static class AuthResponse {
        private boolean success;
        private String message;
        
        // getter和setter
        public boolean isSuccess() { return success; }
        public void setSuccess(boolean success) { this.success = success; }
        public String getMessage() { return message; }
        public void setMessage(String message) { this.message = message; }
    }

    @PostMapping("/login")
    public ResponseEntity<AuthResponse> login(@RequestBody LoginRequest loginRequest) {
        boolean isValid = authService.validateCredentials(loginRequest.getUsername(), loginRequest.getPassword());
        AuthResponse response = new AuthResponse();
        
        if (isValid) {
            response.setSuccess(true);
            response.setMessage("登录成功");
            return ResponseEntity.ok(response);
        } else {
            response.setSuccess(false);
            response.setMessage("用户名或密码错误");
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(response);
        }
    }
}

6. 前端AngularJS登录页面实现

编写登录表单和请求逻辑,用AngularJS的$http发送POST请求到后端接口:

登录页面HTML(login.html)

<!DOCTYPE html>
<html ng-app="loginApp">
<head>
    <title>用户登录</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
    <script src="app.js"></script>
</head>
<body ng-controller="LoginController">
    <div style="width: 300px; margin: 50px auto;">
        <h2>登录</h2>
        <form ng-submit="login()" style="display: flex; flex-direction: column; gap: 10px;">
            <div>
                <label>用户名:</label>
                <input type="text" ng-model="credentials.username" required style="width: 100%;">
            </div>
            <div>
                <label>密码:</label>
                <input type="password" ng-model="credentials.password" required style="width: 100%;">
            </div>
            <button type="submit" style="padding: 8px;">登录</button>
        </form>
        <div ng-if="errorMessage" style="color: red; margin-top: 10px;">{{errorMessage}}</div>
    </div>
</body>
</html>

AngularJS控制器(app.js)

var app = angular.module('loginApp', []);

app.controller('LoginController', function($scope, $http) {
    $scope.credentials = {
        username: '',
        password: ''
    };
    $scope.errorMessage = '';

    $scope.login = function() {
        $http.post('http://localhost:8080/api/login', $scope.credentials)
            .then(function(response) {
                if (response.data.success) {
                    // 登录成功,跳转到主页
                    window.location.href = '/home.html';
                } else {
                    $scope.errorMessage = response.data.message;
                }
            })
            .catch(function(error) {
                $scope.errorMessage = '登录失败,请稍后重试';
                console.error('登录请求错误:', error);
            });
    };
});
关键注意事项
  • 密码加密:绝对不要明文存储密码,注册用户时必须用BCryptPasswordEncoder加密后再存入数据库,登录时用matches方法验证。BCrypt会自动处理盐值,安全性远高于MD5等哈希算法。
  • 跨域配置:如果前后端部署在不同端口/域名,必须在后端配置CORS(比如@CrossOrigin注解),否则前端会被浏览器阻止请求。
  • 安全加固:可以考虑添加JWT令牌,登录成功后返回JWT,后续请求携带令牌验证身份,比单纯的用户名密码验证更安全。
  • 异常处理:后端可以添加全局异常处理器,捕获数据库异常、空指针异常等,返回统一的错误格式,方便前端处理。
  • 日志记录:在Service或Controller中添加日志(比如用org.slf4j.Logger),记录登录成功/失败的事件,方便排查问题。

内容的提问来源于stack exchange,提问作者Rahul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:45:41