In my server, I create session by userId, create and valid csrf-token by userId too, like this:
session = createSession(userId)
csrf-token = createToken(userId)
validateToken(userId,csrf-token)
In this case, if one user login in, he gets session-1 and csrt-token-1.
Then he logout and login angin, he gets session-2 and csrt-token-2, but he can still use csrt-token-1 to do post request with session-2, because session-2 has the same userId as session-1 (csrt-token-1 is not expired).
My question is:
Can I use an old crsf-token which is not expired to do request with new session?
csrt-token-1 can protect my server from csrf-attack, but I feel this is not right.
Related
Is there some API in Wordpress to 'authorize' a user? Let's say I want to implement something like:
if (1 == 1) {
user_authenticate('userXY');
}
The method user_authenticate would initialize the session and send the necessary cookies to the user.
Thank you!
There are a number of built-in WordPress functions that you may find helpful for what you're trying to do. I'm guessing the most helpful would be the wp_set_auth_cookie function (See: https://developer.wordpress.org/reference/functions/wp_set_auth_cookie/).
You may want to try something like:
wp_clear_auth_cookie();
$user = get_user_by('login', $username);
$user_id = $user->ID;
wp_set_auth_cookie($user_id);
wp_set_current_user($user_id);
or something to that effect.
Here are some other user/cookie/session functions available to you:
In the wp-includes/pluggable.php file
wp_validate_auth_cookie - Validates authentication cookie.
wp_generate_auth_cookie - Generates authentication cookie contents.
wp_parse_auth_cookie - Parses a cookie into its components.
wp_set_auth_cookie - Sets the authentication cookies based on user ID.
wp_clear_auth_cookie - Removes all of the cookies associated with authentication.
wp_get_current_user - Retrieve the current user object.
wp_set_current_user - Changes the current user by ID or name.
In the wp-includes/user.php file
wp_get_session_token - Retrieve the current session token from the logged_in cookie.
wp_get_all_sessions - Retrieve a list of sessions for the current user.
wp_destroy_current_session - Remove the current session token from the database.
wp_destroy_other_sessions - Remove all but the current session token for the current user for the database.
wp_destroy_all_sessions - Remove all session tokens for the current user from the database.
There is also a great plugin (only one file long) that does this sort of thing called User Switching (See: https://wordpress.org/plugins/user-switching/). You may also find some very helpful code from poking around that file.
So, maybe I missed this somewhere in the docs but I couldn't find anything of the sort.
I wan't my users to have to type in their current password to be able to create a new one. From what I understand if the user is authenticated he is able to update his password without providing his current one.
Even if this might be somewhat secure I would rather have him type his old one to prevent people from going on already authenticated sessions from say family members or so and changing the pw.
Is there any way to do this?
(I have no problem using the Admin SDK since I already set up a server for these kind of things)
UPDATE: (Use - reauthenticateWithCredential)
var user = firebaseApp.auth().currentUser;
var credential = firebase.auth.EmailAuthProvider.credential(
firebase.auth().currentUser.email,
providedPassword
);
// Prompt the user to re-provide their sign-in credentials
user.reauthenticateWithCredential(credential).then(function() {
// User re-authenticated.
}).catch(function(error) {
// An error happened.
});
PREVIOUS VERSION
you can use reauthenticate API to do so. I am assuming you want to verify a current user's password before allowing the user to update it. So in web you do something like the following:
reauthenticateAndRetrieveDataWithCredential- DEPRECATED
firebase.auth().currentUser.reauthenticateAndRetrieveDataWithCredential(
firebase.auth.EmailAuthProvider.credential(
firebase.auth().currentUser.email,
providedPassword
)
);
If this succeeds, then you can call
firebase.auth().currentUser.updatePassword(newPassword);
How can check, on server side route, if user is logged?
I would add check on 'before', but Metor.user() don't work here.
thanks in advance.
p.s. I have found How to get Meteor.user() to return on the server side?, but not work on iron-router
I'm afraid that this is not possible. I guess that the problem comes from the fact that you're trying to connect to the server with two different protocols - both literally and in logically - so there is no obvious way to relate this two actions.
There is, however, a pretty simple solution that may suit your needs. You'll need to develop a simple system of privileges tokens, or secret keys, or whatever you call them. First, create a server method
var Secrets = new Meteor.Collection("secrets"); // only on server!!!
Meteor.methods({
getSecretKey: function () {
if (!this.userId)
// check if the user has privileges
throw Meteor.Error(403);
return Secrets.insert({_id: Random.id(), user: this.userId});
},
});
Then, you can now use it on the client to get the secretKey which attach to your AJAX request (or something), either within the HTTP header or in the URL itself. Fear not!
They will all be encrypted if you're using HTTPS.
On the server side you can now retrieve the secretKey from the incoming request and check if it is present in the Secrets collection. You'll know then if the user is granted certain privileges or not.
Also you may want to remove your secret keys from the collection after some time for safety reasons.
If what you're looking to do is to authenticate the Meteor.user making the request, I'm currently doing this within the context of IronRouter.route(). The request must be made with a valid user ID and auth token in the header. I call this function from within Router.route(), which then gives me access to this.user:
###
Verify the request is being made by an actively logged in user
#context: IronRouter.Router.route()
###
authenticate = ->
# Get the auth info from header
userId = this.request.headers['x-user-id']
loginToken = this.request.headers['x-auth-token']
# Get the user from the database
if userId and loginToken
user = Meteor.users.findOne {'_id': userId, 'services.resume.loginTokens.token': loginToken}
# Return an error if the login token does not match any belonging to the user
if not user
respond.call this, {success: false, message: "You must be logged in to do this."}, 401
# Attach the user to the context so they can be accessed at this.user within route
this.user = user
###
Respond to an HTTP request
#context: IronRouter.Router.route()
###
respond = (body, statusCode=200, headers={'Content-Type':'text/json'}) ->
this.response.writeHead statusCode, headers
this.response.write(JSON.stringify(body))
this.response.end()
This code was heavily inspired by RestStop and RestStop2. It's part of a meteor package for writing REST APIs in Meteor 0.9.0+ (built on top of Iron Router). You can check out the complete source code here:
https://github.com/krose72205/meteor-restivus
I'm creating a gateway app which will control access to various other apps (tools).
On visiting the site the user is identified and a list of tools they have access to is displayed. Clicking the link takes the user to the tool. The URL is affixed with a token as a querystring. The token is encrypted.
On arriving at the tool site the system checks to see if there is a querystring with a token. It checks to see if the token is valid (the date is part of the encryption). If OK then the token is also saved as cookie which is valid for 8h and access is granted.
If the user hits the Tool site directly from a bookmark the system once again checks to see if there is a token and that it is valid. If no token is passed as a querystring then the system will see if it still has a valid cookie. If there is no valid token or cookie the site invokes a response.redirect to the gateway together with two querystrings t and r. t is the tool's numeric ID and r is the Tools URL.
What should happen is that the user will be redirected to the Gateway which will check to see if the user has access to tool id t and if the have redirect back to r with a fresh token appended as a querystring.
My code has the following....
Private GatewayURL As String = "http://GatewayURL/default.aspx?t=2&r="
Private ToolURL As String = "http://ToolURL/default.aspx"
In my page load I have….
…
If AuthenticationPass = False Then
'We are not authenticated...
Response.Redirect(GatewayURL & ToolURL, True)
End If
…
Unfortunately when this is triggered I get the following error...
Invalid path for child request 'http://GatewayURL/default.aspx'. A virtual path is expected.
I've run out of ideas on resolving this.... any help appreciated.
You should URL encode your query string parameters:
Response.Redirect(GatewayURL & HttpUtility.UrlEncode(ToolURL), True)
so that you redirect to:
http://GatewayURL/default.aspx?t=2&r=http%3A%2F%2FToolURL%2Fdefault.aspx
instead of:
http://GatewayURL/default.aspx?t=2&r=http://ToolURL/default.aspx
The second is a pretty broken url.
I have a web based application that allows a user to point their DNS at my IP and my app will serve up their content based on the domain name I see in the HTTP host header. I should point out this is done by the application, not by the actual HTTP server(apache), it is a rebranded app sort of thing. The problem I have is that I would like the users to be able to login through a form on the served page and somehow stay within the domain of the user. This is easy, unless you want security. I would have to have a SSL cert installed for every domain to pull this off. Right now I can do it by submitting the form to a domain with an SSL cert installed, but due to browser security I can't exactly set the required cookies on the original domain.
Does anyone know a way I can securely log in users through the app that does not involve installing a lot of ssl certs. I can think of some convoluted ways using redirects or other mechanisms, but it is not that clean. I don't mind a submit to the secure url and a redirect, it's just setting the cookie can't be done.
I've done this before using the following method...
Create auth key on server 1.
create_auth_key
expires = time + expire_time
data = username + '|' + password + expires
secret = 'my secret key'
hash = md5( data + secret )
key = base64( data ) + hash
On server two you pass the newly created authkey
valid_auth_key(key)
hash = key[-hash_size:]
b64data = key[:-hash_size]
data = base64decode( b64data )
data_hash = md5( data + secret )
if data_hash != hash:
return false # invalid hash
data_parts = data.split('|')
user = data_parts[0]
password = data_parts[1]
expires = data_parts[2]
if now > expires:
return false # url expired
return true
It's kind of quick and dirty but only relies on simple data passed via URL. The down side is that a specific url is all that's required to login and someone could share that url for a period of time. You also have to make sure your expiration time is not greater than the time difference between servers.
A common trick is to pass data in the URL. Facebook Connect does this. You can redirect from one domain to the other with a session token in the URL and then verify the token (perhaps convert to a cookie) when the request comes in on the other domain. Edit: the MSDN article that Facebook links to has much more detail.