java.sql.SQLSyntaxErrorException: ORA-00972: 标识符太长

kit*_*ttu 1 java oracle jwt

我试图在将 JWT 令牌发送到客户端之前在数据库中插入特定 user_id(column) 的 JWT 令牌。

public void saveTokenToDB(String email, String token) {
        try {
            String query = "Update TBL_USER set USR_TOKEN ="+token+" where email="+email+" ";
            Connection con = DBConnection.getConnection();
            PreparedStatement statement = con.prepareStatement(query);
            int result = statement.executeUpdate();
            System.out.println("result is: " + result);

        } catch (Exception ex) {
            System.out.println("Error in TokenSaverDAO class");
            ex.printStackTrace();
        }
    }
Run Code Online (Sandbox Code Playgroud)

但我收到一个错误:

java.sql.SQLSyntaxErrorException: ORA-00972: identifier is too long
Run Code Online (Sandbox Code Playgroud)

我尝试使用 CLOB 作为列类型,但仍然出现相同的错误。

这是我的令牌:

eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvcnRoLmNvbSIsInN1YiI6IlJUSCIsImV4cCI6MTQ1MzE1NDI2MywiZW1haWwiOiJraXJpdGkuazk5OUBnbWFpbC5jb20ifQ
.X13gGlAIbS3bh-2eX-SdZjglA-QSMW5Gz_IokRdGWXqmmdQDYHNgbKpuqhtf7EqSLN_I8Qx80FMKzVXn9G4O1-bhXCDkWWHkPaC
WN16RJazyJdWqzHHTVHD2AN-mF6eG7KFto5HlvFfIdvgQZszAzqS_cVGQHM1hIn-r5sCrkI4
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以将令牌保存在数据库中,或者可能会为每个登录的用户将其保存在地图中。如果我使用地图,那么每次用户请求资源时如何进行身份验证。

现在我正在这样做:

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        // Get the HTTP Authorization header from the request
        String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        // Check if the HTTP Authorization header is present and formatted correctly 
        if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer ")) {
            throw new NotAuthorizedException("Authorization header must be provided");
        }

        // Extract the token from the HTTP Authorization header
        String token = authorizationHeader.substring("Bearer".length()).trim();
        System.out.println("request token is: " + token);

        try {

            // Validate the token
            validateToken(token);

        } catch (Exception e) {
            requestContext.abortWith(
                    Response.status(Response.Status.UNAUTHORIZED).build());
        }
    }

    private void validateToken(String token) throws Exception {
        // Check if the token was issued by the server that is saved in Database and if it's not expired
        // Throw an Exception if the token is invalid
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有两个问题:

  1. 如何修复 java.sql.SQLSyntaxErrorException: ORA-00972: identifier is too long
  2. 将令牌保存在地图或缓存中并对每个资源请求执行 JWT 身份验证

a_h*_*ame 5

这是你的问题:

String query = "Update TBL_USER set USR_TOKEN ="+token+" where email="+email+" ";
Run Code Online (Sandbox Code Playgroud)

假设token包含"eyJhbGciOiJSUzI1NiJ9"您使用此语句结束的字符串

Update TBL_USER set USR_TOKEN = eyJhbGciOiJSUzI1NiJ9
Run Code Online (Sandbox Code Playgroud)

它引用名为eyJhbGciOiJSUzI1NiJ9. 如果您的令牌较短,您会收到“无效标识符”错误。但是,由于标识符限制为 30 个字符(因此最基本的语法检查失败,Oracle 甚至不会开始检查是否存在具有该名称的列),因此令牌的超长值会破坏早期状态中的 SQL 解析器。


字符串常量需要用单引号括起来,例如'foobar',所以你的 Java 代码需要是:

String query = "Update TBL_USER set USR_TOKEN = '" + token + "' where email = '"+email+"' ";
Run Code Online (Sandbox Code Playgroud)

但是如果变量emailtoken包含单引号,这将中断。要解决这个问题,最好正确使用 PreparedStatement:

String query = "Update TBL_USER set USR_TOKEN = ? where email = ?";
PreparedStatement statement = con.prepareStatement(query);
statement.setString(1, token);
statement.setString(2, email);
int result = statement.executeUpdate();
Run Code Online (Sandbox Code Playgroud)