-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unpermitted parameter: session #130
Comments
This is a Rails behavior. Try to create an other controller, you'll have : Parameters: { "foo" => "bar", "ControllerName" => { "foo" => "bar" } } |
@nicolas-besnard doesn't this means that I need to copy all the session controller functionality to this new controller? If there is a session controller in this gem, why would I create a new one? And just to update my issue, when I created the user in console, I had validation errors saying UID and PROVIDER can not be blank. So I added a random UID and provider a random word, in my case "basic". |
What I meant is that the params if you need more parameters on When you |
I don't need more params, I just don't understand what session param is doing here and how do I premit it in this controller: https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/controllers/devise_token_auth/sessions_controller.rb or do I even need this session param? may be it's a bug that comes from ng-token-auth, why in the world would be useful to have a request with duplicated email and password param? Why the param looks like this: Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "session"=>{"email"=>"[email protected]", "password"=>"[FILTERED]"}} and why do I need email and password in param root and in session? And if it needs to be in session too, how do I override the resource_params in sessions controller to allow session param too? def resource_params
params.permit(devise_parameter_sanitizer.for(:sign_in))
end where can I find devise_parameter_sanitizer.for(:sign_in) |
`why do I need email and password in param root and in session?`` You don't, it's a normal Rails behavior. When you call an url http://yousite.com/foo?bar=title You'll end with : Parameters: { "bar" => "title", "ControllerName" => { "bar" => "title" } }
In the Devise documentation. |
Found the devise_parameter_sanitizer method. Thanks, but I don't think I need to touch that. Parameters: {"utf8"=>"✓", "authenticity_token"=>"+Y0glSMrpy5CHm8=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"} there is no session param and this is how a normal Rails behavior should be. However, considering that I am not using a form_for helper in this case, it's just a plain html form with some angular things in it, <form ng-submit="submitLogin(loginForm)" role="form" ng-init="loginForm = {}"> and the important part might be: ng-submit="submitLogin(loginForm)" probably the function submitLogin from angular module ng-token-auth somehow adds this session param. |
in curl -XPOST -H 'Content-Type: application/json' http://localhost:8080/users/auth/sign_in -d '{"username": "foo", "password": "bar"}' In this case, Rails will map the request's params in a key with the name of your controller : Parameters: { "bar" => "title", "ControllerName" => { "bar" => "title" } } TRUST ME, THIS IS A NORMAL BEHAVIOR IN RAILS try to hit a route with a POST request in curl. Now, in Devise (without Parameters: { "ControllerName" => { "bar" => "title" } } |
"THIS IS A NORMAL BEHAVIOR IN RAILS" - ok, I got it :) "your form value is mapped" - No my friend, the value is not mapped to user the way rails does, cause the form I use is a template from assets used by angular. Here is an example of it: Thank you for your time. btw, where is the controller name in this request: Parameters: {"utf8"=>"✓", "authenticity_token"=>"+Y0glSMrpy5CHm8=", "user"=>{"email"=>"[email protected]", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"} just wondering, this request is consumed by sessions_controller from devise, where is the session param? If you have time please explain this. Thank you so much again. |
There's no session param (nore ControllerName param), because you don't specify any params who's not an object. As I said, you should try to hit this same route with a curl request an add an other parameter such as : curl -XPOST -H 'Content-Type: application/json' http://localhost:3000/ -d '{"user": { "email": "[email protected]", "password": "password" }, "orphan_parameter": "fooBar" }' Sorry if I sound "harsh". Wasn't my intention. |
"Sorry if I sound "harsh"" - No problem, honestly, I asked for it.. anyway.. let me explain where my problem starts. It started right here: he uses devise_token_auth with ng-token-auth, as you'll see, there is no form in a rails way, there is an angular template that stores this form, and this form has ng-model="loginForm.password" and ng-model="loginForm.email" that stores the email and password, and ng-submit="submitLogin(loginForm)" takes care that on submit these values goes to some angular controller and using the params he got it makes the get request to the api Started POST "/api/auth/sign_in" for 127.0.0.1 at 2015-02-03 22:19:48 +0200
Processing by DeviseTokenAuth::SessionsController#create as HTML
Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "session"=>{"email"=>"[email protected]", "password"=>"[FILTERED]"}}
Unpermitted parameter: session
User Load (0.6ms) SELECT "users".* FROM "users" WHERE (uid = '[email protected]' AND provider='email') ORDER BY "users"."id" ASC LIMIT 1
Completed 401 Unauthorized in 5ms (Views: 1.6ms | ActiveRecord: 0.6ms) so I suspect it's angular that pust the session param in the request, cause I tried to map email and password field into user, like user[email] and user[params], and the request did not changed at all (refreshed the page, restarted server), the request was the same, that's why I am thinking that request to the api is done by angular with this dumb session param that is not permitted by devise, normally devise should get something like: Parameters: {"user" => {"email"=>"[email protected]", "password"=>"[FILTERED]"}, ...} and based on params[:user][:email] and params[:user][:password] do the authentication. If you have time and will to look over that tutorial hoping you might spot something I missed, I would appreciate it very much. Else, I appreciate it anyway :) and this issue can be closed. But someone might get into the same issue in the future. |
Where did you try do to this ? You have to do it in your Angular controller, not in the view.
Once again, it's not done by Angular, it's a normal Rails Behavior ^^ |
@rmagnum2002 - can you post the body of the request? This can be found in the "network" tab of your browser's web inspector. |
@lynndylanhurley sure, headers tab: https://gist.github.com/rmagnum2002/89453c9446850131aa33 |
That looks correct - it's just the response for an invalid username and/or password. What's the problem again? |
Well, I am sure 100% that the pass and email are correct. Parameters: {"user" => {"email"=>"[email protected]", "password"=>"[FILTERED]"}, ...} and devise actually permit this params, as it builds it from the resource name (user in our case) and email + password for session create process. Now, your gem has devise as dependency, right? So it means in sessions controller your have: def resource_params
params.permit(devise_parameter_sanitizer.for(:sign_in))
end where devise_parameter_sanitizer is a method/class from devise gem In the end params permit in your gem's session controller will look like: params.permit(user: [:email, :password]) and this will work with the request in form like this: Parameters: {"user" => {"email"=>"[email protected]", "password"=>"[FILTERED]"}, ...} but when I am using it with angular, email and password param comes out of user param {"email"=>"[email protected]", "password"=>"[FILTERED]", "session"=>{"email"=>"[email protected]", "password"=>"[FILTERED]"}} session param and content of it is not permitted by sessions controller, params email and password are not in user => {} hash.. so.. there is no way this will work out of the box.. I need somehow to tell angular how to build the request. If it does not make any sense what I am saying, just leave it and close the issue. |
The params shouldn't be nested inside a Instead of this:
The params should look like this:
Can you think of any reason that the params are nested inside the |
I am not saying they should be, but knowing the way devise and permit.params in devsie works, email and password should be nested in user param, cause this is the way sessions controller permits it. Or, let's forget about the params are sent in request, and I'll ask you a question: |
Face-palm, I think I am getting closer. That tutorial did not mentioned anything about that the user I create in console should have: and unauthorized error I got because app was looking for user with uid "[email protected]" and provider "email", so it wasn't found. now I have another problem to handle, but it's not related to this gem. 2.2.0 :004 > User.last
User Load (1.0ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
=> #<User id: 1, provider: "email", uid: "[email protected]", encrypted_password: "$2a$10$22mHqp39i.8QhMl2su3ef.xg8tPHTqJt5j72EOg4MLJ...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, confirmation_token: "08c9ca9cf521287016bf94d5af0c05db4484be74d285b0ceb4...", confirmed_at: nil, confirmation_sent_at: "2015-02-05 08:52:04", unconfirmed_email: nil, name: nil, nickname: nil, image: nil, email: "[email protected]", tokens: {}, created_at: "2015-02-05 08:52:04", updated_at: "2015-02-05 08:52:04">
2.2.0 :005 > User.where(uid: '[email protected]', provider: 'email')
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."uid" = $1 AND "users"."provider" = $2 [["uid", "[email protected]"], ["provider", "email"]]
=> #<ActiveRecord::Relation []> Thank you both for your time and patience. |
The way that I understand it, parameter sanitizers are just whitelists. They don't actually modify or re-structure the existing params, they just filter out params that haven't been explicitly allowed. The documentation for strong params is here.
The documentation is here:
I think this gem's behavior has changed since that tutorial was written. Sorry for the confusion - I'll update the docs ASAP! |
I'll create a summary of the issue, if any one follows that tutorial as well: In order to not get Unauthorized error user must have the following data filled in:
Also, when you create the user and specify the provider as "email", the UID field will be automatically set as the email of the user. Unpermitted parameter: session But this does not brakes the sign in in any way, it's just blacklisted. And this is not related with the controller name, cause controller name is 'sessions', but the param is 'session' Investigating. |
Awesome, thanks @rmagnum2002! |
Once again, try to hit a controller with a POST request after defining Take a look at the documentation and just read the first line. I copy it for you, because I'm done trying to make you understand THIS IS NORMAL : You can send parameters like this: {"name": "Konata"} And it will be wrapped into a nested hash with the key name matching the controller's name. For example, if you're posting to UsersController, your new params hash will look like this: {"name" => "Konata", "user" => {"name" => "Konata"}} |
I hit it with a post request from chromes postman plugin, and there were no session param there, if this is a normal rails behavior, why session param is not present when doing requests with postman? Logs from the request with postman:
How come there is no session param if it's a Rails normal behavior? I just don't get it. While post request that comes from angular generates session param:
|
now I got it. well, I'll stay with this message in logs then, till I find a way to override permitted_params. |
On your request, we can see one difference. On the second one (where you do have the session parameter) : According to the doc, you can specify which format you want to wrap. Try to redo your first request but this time add a header |
Wow, what a noob you are talking to... You were right, session param is here if I add Content-Type to header. |
No problem, I face this problem when I started learning Rails. It gave me headache ! |
i've read through this conversation twice, and i still don't know what the solution was. —how does one tell the session controller to permit the session parameter? any advice appreciated |
for those looking for a solution to this problem, there is an initializer file called wrap_parameters.rb in the config folder—there are instructions in the comments of that file for disabling the parameter wrapping behaviour |
This is caused by ActionController ParamsWrapper
This is not a problem as it's a normal Rails behavior.
Or to add in the controller |
@rmagnum2002 |
if you guys have this particular problem and want to get rid the warning because its annoying see more here |
Not solved for me yet |
Create an initializer if it doesn't exist
This is one of those annoying and questionable defaults. Can't say I have ever wanted Rails to wrap parameters automatically. If I want them wrapped I'll wrap them when I send..? |
|
Hi, I get this error when signing in, tried a couple of hours to understand what is wrong and no luck, I even thought to override the devise_token_auth/session controller to permit session param too, but that will be the last thing to do unless I find something better:
Where this session param comes from and what do I do about it. Previous issues related to this didn't helped at all.
Thank you.
The text was updated successfully, but these errors were encountered: