【问题标题】:Proper place for setting form fields in ResourceSupport which don't exist in Entity在 ResourceSupport 中设置实体中不存在的表单字段的正确位置
【发布时间】:2014-09-10 04:34:02
【问题描述】:

我的 REST API 中有一个用于登录用户的模型,对应于用户表(电子邮件和密码作为表列)

@Entity
public class User {

@Id
@GeneratedValues
private Long id;

private String email;
private String password;

+GET , +SET

}

然后是@Controller,它正在使用 JPAService 调用上述用户实体

    @Controller
    @RequestMapping("/rest/auths")
    public class AuthController {

        @Autowired    
        private UserService authService;

        @RequestMapping(value = "/login", method = RequestMethod.POST)
            public @ResponseBody ResponseEntity<AuthLoginFormResource> login(@RequestBody AuthLoginFormResource sentAuth) {

            User user = authService.login(sentAuth.toUser());
            AuthLoginFormResource res = new AuthLoginFormResourceAsm().toResource(user); 

            HttpHeaders headers = new HttpHeaders();
                headers.setLocation(URI.create(res.getLink("self").getHref()));

                return new ResponseEntity<AuthLoginFormResource>(res, HttpStatus.OK);
            }
       }

AuthLoginFormResource:-

        public class AuthLoginFormResource extends ResourceSupport {

            private String email;
            private String password;
            private boolean success;

        public User toUser() { 

            User user = new User(); 
            user.setEmail(email);
            user.setPassword(password);
            //user.setSuccess(false);
            return user;

        }
        +GET, +SET
    }

AuthLoginFormResourceAsm:-

    public class AuthLoginFormResourceAsm extends ResourceAssemblerSupport<User, AuthLoginFormResource> {

        public AuthLoginFormResourceAsm() {
            super(User.class, AuthLoginFormResource.class);
        }

        @Override
        public AuthLoginFormResource toResource(User user) {

            AuthLoginFormResource res = new AuthLoginFormResource();
            res.setEmail(user.getEmail());
            res.setPassword(user.getPassword());
            //res.setSuccess(user.isSuccess()); // Success is not existing in USER

            res.add(linkTo(AuthController.class).withSelfRel());

            return res;
        }

    }

有两个问题 -

  • 我需要发送一个成功标志作为布尔值作为响应,为此我已将布尔值成功添加到 AuthLoginFormResource。但是, AuthLoginFormResource 被设置 仅来自 AuthLoginFormResourceAsm.toResource 方法,而后者又可以 它来自实体用户。作为用户实体模型数据库,其中有 没有成功栏,我无法在这个地方设置成功。

    那么,我应该将虚拟成功字段添加到用户实体并从服务中设置吗 方法,虽然数据库中没有这样的字段或在这里创建一个表示登录表单的新实体并返回?

  • 作为身份验证令牌的另一个字段存在相同问题 它在数据库中不存在,但作为响应的一部分。

在 ResourceSupport 对象中设置此类字段的正确位置是什么 - 在数据库实体内部并从服务返回/在域模型之上创建另一个表单模型实体并从服务返回。

这是我在数据模型和表单不一对一匹配的许多地方面临的基本问题。

【问题讨论】:

  • 现在,我添加了一个名为 UserAuth 的新模型,它扩展了 User 并修改了 Service 以返回 UserAuth 而不是 User。 UserAuth 包含 REST 响应所需的 User 顶部的其他字段
  • 如果您的实体和 ResourceSupport 对象相同(关于字段),那么您不需要单独的类。

标签: java spring spring-mvc spring-hateoas


【解决方案1】:

我强烈推荐以下内容;

  1. 修改UserService.login 方法以根据成功的身份验证返回true 或false,而不是从数据库中检索到用户对象。
  2. 仅返回 true 或 false,状态为 OK 和 FAIL,作为响应的一部分,而不是整个 AuthLoginFormResource。这是一种不好的做法,因为您在往返中来回发送usernamepassword 作为请求和响应的一部分。如果有人窃听,他们可以轻松找出哪些用户名密码有效,哪些无效。

或者

如果您喜欢这种自定义身份验证实现,请考虑使用基本授权、摘要授权或 OAuth。使用 Spring Security,您可以轻松实现上述任何一项。

【讨论】:

  • 感谢@shazin,我已在 getter 的 AuthLoginFormResource 中将 JsonIgnore 添加到密码和电子邮件中。所以,它们并没有被泄露出去。但是,问题还在于用户登录后如何将令牌从服务器发送到 REST API。我正在考虑将此令牌字段添加到服务层并以布尔状态包装在 UserService.login 中 - 我可以使用 Spring Security 获取此令牌
猜你喜欢
  • 2014-04-23
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 1970-01-01
  • 2018-05-07
  • 1970-01-01
  • 2015-12-11
  • 1970-01-01
相关资源
最近更新 更多