有没有办法阻止用户编辑本地存储会话?
Is there a way to prevent users from editing the local storage session?
我正在创建一个关系博客,我在其中使用 ember_simple_auth:session
来存储会话
{"authenticated":{"authenticator":"authenticator:devise","token":"rh2f9iy7EjJXESAM5koQ","email":"user@example.com","userId":1}}
但是,在 Chrome(可能还有其他浏览器)的开发者工具上,很容易编辑电子邮件和用户 ID,以便在页面重新加载时冒充另一个用户。
编辑#1
从与 Joachim 和 Nikolaj 的谈话中,我现在意识到解决此问题的最佳方法是在每次需要时(仅在页面重新加载时)探测 localStorage 的真实性,而不是试图阻止编辑。
为了验证真实性,我创建了一个必须先解决才能使用 AccountSession 的承诺。 promise serverValidation() 请求使用当前 localStorage 信息创建令牌模型,当服务器获取它时,它验证信息并使用类型为令牌的简单用户序列化响应 200如果信息是合法的。您可以在 Source Code.
上查看更多信息
会话帐户
import Ember from 'ember';
const { inject: { service }, RSVP } = Ember;
export default Ember.Service.extend ({
session: service('session'),
store: service(),
serverValidation: false,
// Create a Promise to handle a server request that validates the current LocalStorage
// If valid, then set SessionAccount User.
loadCurrentUser() {
if (!Ember.isEmpty(this.get('session.data.authenticated.userId'))) {
this.serverValidation().then(() => {
return new RSVP.Promise((resolve, reject) => {
const userId = this.get('session.data.authenticated.userId');
// Get User to Session-Account Block
if(this.get('serverValidation') === true) {
return this.get('store').find('user', userId).then((user) => {
this.set('user', user);
resolve();
}).catch((reason) => {
console.log(reason.errors);
var possible404 = reason.errors.filterBy('status','404');
var possible500 = reason.errors.filterBy('status','500');
if(possible404.length !== 0) {
alert('404 | Sign In Not Found Error');
this.get('session').invalidate();
}
else if(possible500.length !== 0) {
alert('500 | Sign In Server Error');
this.get('session').invalidate();
}
reject();
});
}
else{
alert('Session for Server Validation failed! Logging out!');
this.get('session').invalidate();
resolve();
}
});
});
} else {
// Session is empty...
}
},
serverValidation() {
return new RSVP.Promise((resolve) => {
var tokenAuthentication = this.get('store').createRecord('token', {
id: this.get('session.data.authenticated.userId'),
email: this.get('session.data.authenticated.email'),
authenticity_token: this.get('session.data.authenticated.token'),
});
tokenAuthentication.save().then(() => {
this.set('serverValidation',true);
console.log('Server Validation complete with 200');
resolve();
}).catch((reason) => {
this.set('serverValidation',false);
resolve();
});
});
}
});
令牌控制器
# Users Controller: JSON response through Active Model Serializers
class Api::V1::TokensController < ApiController
respond_to :json
def create
if token_by_id == token_by_token
if token_by_email == token_by_id
render json: token_by_id, serializer: TokenSerializer, status: 200
else
render json: {}, status: 404
end
else
render json: {}, status: 404
end
end
private
def token_by_id
User.find(user_params[:id])
end
def token_by_email
User.find_by(email: user_params[:email])
end
def token_by_token
User.find_by(authentication_token: user_params[:authenticity_token])
end
def user_params
ActiveModelSerializers::Deserialization.jsonapi_parse!(params.to_unsafe_h)
end
end
无法阻止用户编辑其本地存储、会话存储或 cookie 的内容。
但这不应该让你担心。通过令牌的值来标识用户。令牌在他登录时由身份验证器生成并发送给他。要通过编辑会话数据来模拟另一个用户,他必须知道其他用户已登录,并且知道该用户的令牌。
我正在创建一个关系博客,我在其中使用 ember_simple_auth:session
来存储会话
{"authenticated":{"authenticator":"authenticator:devise","token":"rh2f9iy7EjJXESAM5koQ","email":"user@example.com","userId":1}}
但是,在 Chrome(可能还有其他浏览器)的开发者工具上,很容易编辑电子邮件和用户 ID,以便在页面重新加载时冒充另一个用户。
编辑#1
从与 Joachim 和 Nikolaj 的谈话中,我现在意识到解决此问题的最佳方法是在每次需要时(仅在页面重新加载时)探测 localStorage 的真实性,而不是试图阻止编辑。
为了验证真实性,我创建了一个必须先解决才能使用 AccountSession 的承诺。 promise serverValidation() 请求使用当前 localStorage 信息创建令牌模型,当服务器获取它时,它验证信息并使用类型为令牌的简单用户序列化响应 200如果信息是合法的。您可以在 Source Code.
上查看更多信息会话帐户
import Ember from 'ember';
const { inject: { service }, RSVP } = Ember;
export default Ember.Service.extend ({
session: service('session'),
store: service(),
serverValidation: false,
// Create a Promise to handle a server request that validates the current LocalStorage
// If valid, then set SessionAccount User.
loadCurrentUser() {
if (!Ember.isEmpty(this.get('session.data.authenticated.userId'))) {
this.serverValidation().then(() => {
return new RSVP.Promise((resolve, reject) => {
const userId = this.get('session.data.authenticated.userId');
// Get User to Session-Account Block
if(this.get('serverValidation') === true) {
return this.get('store').find('user', userId).then((user) => {
this.set('user', user);
resolve();
}).catch((reason) => {
console.log(reason.errors);
var possible404 = reason.errors.filterBy('status','404');
var possible500 = reason.errors.filterBy('status','500');
if(possible404.length !== 0) {
alert('404 | Sign In Not Found Error');
this.get('session').invalidate();
}
else if(possible500.length !== 0) {
alert('500 | Sign In Server Error');
this.get('session').invalidate();
}
reject();
});
}
else{
alert('Session for Server Validation failed! Logging out!');
this.get('session').invalidate();
resolve();
}
});
});
} else {
// Session is empty...
}
},
serverValidation() {
return new RSVP.Promise((resolve) => {
var tokenAuthentication = this.get('store').createRecord('token', {
id: this.get('session.data.authenticated.userId'),
email: this.get('session.data.authenticated.email'),
authenticity_token: this.get('session.data.authenticated.token'),
});
tokenAuthentication.save().then(() => {
this.set('serverValidation',true);
console.log('Server Validation complete with 200');
resolve();
}).catch((reason) => {
this.set('serverValidation',false);
resolve();
});
});
}
});
令牌控制器
# Users Controller: JSON response through Active Model Serializers
class Api::V1::TokensController < ApiController
respond_to :json
def create
if token_by_id == token_by_token
if token_by_email == token_by_id
render json: token_by_id, serializer: TokenSerializer, status: 200
else
render json: {}, status: 404
end
else
render json: {}, status: 404
end
end
private
def token_by_id
User.find(user_params[:id])
end
def token_by_email
User.find_by(email: user_params[:email])
end
def token_by_token
User.find_by(authentication_token: user_params[:authenticity_token])
end
def user_params
ActiveModelSerializers::Deserialization.jsonapi_parse!(params.to_unsafe_h)
end
end
无法阻止用户编辑其本地存储、会话存储或 cookie 的内容。
但这不应该让你担心。通过令牌的值来标识用户。令牌在他登录时由身份验证器生成并发送给他。要通过编辑会话数据来模拟另一个用户,他必须知道其他用户已登录,并且知道该用户的令牌。