我在我的一个项目中使用ServiceStack作为基础库。 我将我的应用程序构建在两部分API和WEB应用程序中,它们是独立的项目和存储库。
身份验证应该在API层上进行,并且应该在那里缓存。我在API服务器中使用Ormlite缓存客户端。
在API AppHost.cs
中var dbFactory = new OrmLiteConnectionFactory("ConnectionString",SqlServerDialect.Provider);
container.RegisterAs<OrmLiteCacheClient, ICacheClient>();
container.Resolve<ICacheClient>().InitSchema();
Plugins.Add(new AuthFeature(() => new APISession(),
new IAuthProvider[] {
new APICredentialsAuthProvider(new AppSettings())
}));
在APICredentialsAuthProvider中,我正在保存会话,该会话存储在CacheEntry
表中的Db中
我正在使用apiurl/auth
通过ajax调用在Web应用程序中对用户进行身份验证,并使用AuthenticateResponse
返回sessionId
。
我将此会话ID更新为Cookie s-id
,稍后更新为预先请求过滤器,具体取决于ss-id
或ss-pid
中正在更新的请求类型。
//Inside Web application apphost
this.PreRequestFilters.Add((req, res) =>
{
System.Net.Cookie cookie = req.Cookies["s-id"];
req.Cookies["ss-id"] = cookie;
req.SetSessionId(cookie.Value)
});
这种方法不会从我的案例中的Ormlite缓存中获取会话,也不会在Web和Api应用程序中提供相应的配置。
实现这一目标的最佳方式是什么?
但是我可以使用缓存客户端
访问会话//Inside Web application apphost
this.PreRequestFilters.Add((req, res) =>
{
System.Net.Cookie cookie = req.Cookies["s-id"];
req.Cookies["ss-id"] = cookie;
req.SetSessionId(cookie.Value);
APISession cachedSession = GetCacheClient(req).Get<APISession(SessionFeature.GetSessionKey(cookie.Value));
WEBSession session.PopulateWith<WEBSession, APISession>(cachedSession);
});
这工作正常,我能够获取会话,但通过将此放入预请求过滤器增加来自我的Web应用程序的db调用(在每个请求上)。
是否有可用的替代解决方案?
提前致谢!!
答案 0 :(得分:3)
如果您负载均衡多个网络应用在同一个域后面,那么使用OrmLiteCacheClient
之类的任何ss-id/ss-pid
都会发送ServiceStack&#39; s http://example.org/app1 -> http://internal:8001/
/app2 -> http://internal:8002/
/app3 -> http://internal:8003/
在向任一应用程序提出请求时使用Cookie:
OrmLiteCacheClient
然后,只要每个应用配置相同的IRequest.Items
,就可以在所有3个应用中看到在一个应用中创建的会话。
您可以通过在req.Items[Keywords.Session] = session;
上设置该请求来阻止进一步的数据库访问以检索该请求的会话,例如:
IRequest
然后,对该请求的会话的任何访问都将从import React from 'react';
import Question from './Question';
import firebase from 'firebase';
var questions = [{ qtext : "", options: [], id:0, answer: ""}, { qtext : "", options: [], id:1, answer: "" }];
const QuizBuilderForm = React.createClass({
getInitialState: function() {
return {
questions
};
},
addQuestion: function(questions, id) {
questions = this.state.questions;
questions.push({ qtext : "", options: [], id: this.state.questions.length });
this.setState({
questions: questions
});
},
handleSubmit: function(event) {
event.preventDefault();
console.log(this.state.questions);
this.firebaseRef = firebase.database().ref('quizzes');
this.firebaseRef.push({
question: this.state.questions
});
this.refs.form.reset();
this.setState({
question: [{ qtext : "", options:[], id: 0, answer: ""}, {qtext: "", options:[], id: 1, answer: ""}]
});
},
render: function() {
{this.state.questions.map((question, index) => {
<Question {...this.props} key={index} index={index} question={question} />
console.log(question);
}
)};
return (
<form className="quiz-form" onSubmit={this.handleSubmit} ref="form">
<Question />
<button type="button" className="add-question" onClick= {this.addQuestion} disabled={this.state.questions.length === 5}>{this.state.questions.length < 5 ? 'Add another question' : 'Question limit reached!'}</button>
<button type="submit">Create Quiz</button>
</form>
);
}
});
export default QuizBuilderForm;
项词典中解析,而不是点击数据库。
另一种可让您在所有3个应用中进行身份验证的Auth解决方案是使用无状态distributed Caching Providers。