Play Framework 项目中所有操作和视图的通用代码
Common code for all actions and views in Play Framework project
我想在我的 Web 项目的每个页面上显示当前经过身份验证的用户。
我使用 @Security.Authenticated
注释来限制用户访问。
我有一个授权逻辑(方法),它使用 user_id
会话值从数据库中检索当前用户数据。
所以,有几个问题需要解决:
- 我应该在哪里放置
getCurrentUser()
方法以便在所有控制器的所有操作之前执行它?
- 如何使
currentUser
值在所有视图中可用?
- 如何跳过某些操作的身份验证?
我现在所拥有的只是为了一个行动。我不想为其他操作重复此代码?我需要它为整个项目工作:
- 在所有操作之前执行
getCurrentUser()
以获得currentUser
值;
- 使
currentUser
值在视图中可用
控制器:
@Security.Authenticated(Secured.class)
public class UsersController extends Controller {
public Result index() {
return ok(index.render(getCurrentUser()));
}
private User getCurrentUser() {
return User.find.byId(Long.parseLong(request().username()));
}
}
查看(index.scala.html):
@(currentUser: User)
<p>Hello, @currentUser.name</p>
我打算将此视图代码放入所有视图共享的 main.scala.html
文件中。
对于问题的第 1 部分:
使用 Play HTTP 过滤器,您可以拦截每个 http 请求。您可能还想阅读 this.
对于您问题的第 2 部分: 这实际上取决于您希望通过在内存中保留 "currentUser" 来获得什么。你想在内存中保留一个 POJO 吗?或者只是您用户的字符串表示形式(可能 JSON)?持续多长时间?
如果你想要一个 POJO,你可能想要使用 Http.Context.args。这允许您将 Map 存储到内存中。但是,这只是有效的 PER 请求。这是 JavaDoc。
还有其他机制可以使字符串在内存中的保存时间更长。您可以使用位于 www.playframework.com/documentation/2.5.x/JavaSessionFlash 的 Flash 或 Session Scope。
Flash 范围在内存中保留一个字符串,直到会话的 NEXT 请求。会话范围与会话一样长(有时可能比您预期的要长),因为会话没有技术超时。如果有帮助,这些字符串可能是 JSON。
还有另一种方法可以将 POJO 存储得比 http 请求更长。这是播放缓存 API。您可以在这里阅读更多相关信息:www.playframework.com/documentation/2.5.x/JavaCache.
您也可以实现自己的自定义缓存。
最后,您还可以使用 API 端点来检索 USER。这可能很昂贵,但这要视情况而定。您也可以将此方法与某种缓存结合使用。
需要考虑的一些问题:
- 我需要保留在内存中的最小表示是什么?
- 我需要保留此内存的最短时间是多少?
- 我想要什么形式的代表?细绳? JSON? POJO?
- 谁需要访问此表示?客户?服务器?
P.S。我的代表率很低,所以我一次不能 post 超过 2 个链接。这就是为什么一些 "links" 被 post 编辑为文本。
我想在我的 Web 项目的每个页面上显示当前经过身份验证的用户。
我使用 @Security.Authenticated
注释来限制用户访问。
我有一个授权逻辑(方法),它使用 user_id
会话值从数据库中检索当前用户数据。
所以,有几个问题需要解决:
- 我应该在哪里放置
getCurrentUser()
方法以便在所有控制器的所有操作之前执行它? - 如何使
currentUser
值在所有视图中可用? - 如何跳过某些操作的身份验证?
我现在所拥有的只是为了一个行动。我不想为其他操作重复此代码?我需要它为整个项目工作:
- 在所有操作之前执行
getCurrentUser()
以获得currentUser
值; - 使
currentUser
值在视图中可用
控制器:
@Security.Authenticated(Secured.class)
public class UsersController extends Controller {
public Result index() {
return ok(index.render(getCurrentUser()));
}
private User getCurrentUser() {
return User.find.byId(Long.parseLong(request().username()));
}
}
查看(index.scala.html):
@(currentUser: User)
<p>Hello, @currentUser.name</p>
我打算将此视图代码放入所有视图共享的 main.scala.html
文件中。
对于问题的第 1 部分: 使用 Play HTTP 过滤器,您可以拦截每个 http 请求。您可能还想阅读 this.
对于您问题的第 2 部分: 这实际上取决于您希望通过在内存中保留 "currentUser" 来获得什么。你想在内存中保留一个 POJO 吗?或者只是您用户的字符串表示形式(可能 JSON)?持续多长时间?
如果你想要一个 POJO,你可能想要使用 Http.Context.args。这允许您将 Map 存储到内存中。但是,这只是有效的 PER 请求。这是 JavaDoc。
还有其他机制可以使字符串在内存中的保存时间更长。您可以使用位于 www.playframework.com/documentation/2.5.x/JavaSessionFlash 的 Flash 或 Session Scope。
Flash 范围在内存中保留一个字符串,直到会话的 NEXT 请求。会话范围与会话一样长(有时可能比您预期的要长),因为会话没有技术超时。如果有帮助,这些字符串可能是 JSON。
还有另一种方法可以将 POJO 存储得比 http 请求更长。这是播放缓存 API。您可以在这里阅读更多相关信息:www.playframework.com/documentation/2.5.x/JavaCache.
您也可以实现自己的自定义缓存。
最后,您还可以使用 API 端点来检索 USER。这可能很昂贵,但这要视情况而定。您也可以将此方法与某种缓存结合使用。
需要考虑的一些问题:
- 我需要保留在内存中的最小表示是什么?
- 我需要保留此内存的最短时间是多少?
- 我想要什么形式的代表?细绳? JSON? POJO?
- 谁需要访问此表示?客户?服务器?
P.S。我的代表率很低,所以我一次不能 post 超过 2 个链接。这就是为什么一些 "links" 被 post 编辑为文本。