API Authentication with JSON Web Tokens (JWT) and Knock Discussion
Good tutorial Chris. Will be nice if you can create a complete tutorial or tutorials using devise. In my particular case I'm looking for something like this:
How to send and manage all these things (Of course I understand if you don't cover a front-end part)
I read materials like this: https://www.sitepoint.com/i... but still not clear and I think with you we can have even best practices.
Awesome episode, but how do u deal with authorization? I have been using cancancan with devise. Currently i have a project with devise and cancancan and i need JWT for other model. How can i solve it on the same way?
Anything client side is just going to be for displaying the UI and therefore should never be trusted so the server will still need to implement authorization as you normally would.
How do you customize what is required to authenticate the user? For example, you're using email and password to authenticate. In my app, an email is optional and a username is required. So I'd like to authenticate using username and password. Right now, however, if I create a user with a username and a null email, I am able to receive a token by just using "auth[password]=password". I'm assuming this is because Knock default uses email (which is null in this case and would pass authentication). Any tips?
Oops, looks like I only needed a few more minutes of reading the Knock docs :p
Knock does use email by default, and you have to specify if you want to use something else. Read here: https://github.com/nsarno/k...
Basically, you need to add this to the User model (replacing 'username' with whatever you need):
def self.from_token_request request
username = request.params["auth"] && request.params["auth"]["username"]
self.find_by username: username
That turned out nice and simple! :) I hadn't actually customized it to be username/pw but that looks pretty much exactly like what I imagined you'd have to do. Nice and simple, thanks for sharing your solution. 👍
I'd advise against adding the email address to the payload. The purpose of tokens is being able to store them client-side in a secure fashion. By adding the email address to the token, you'd expose 50% of your login credentials.
That's not much to worry about because if someone gets your token, they have full access to your account and can do anything they want. You've got much bigger problems in that situation because your JWTs should never be exposed.
Yes, this is about a worst-case scenario, as it is often in the context of security. You would want to delete the token and reissue a new one ASAP. If you added your email address to the token, that's now out in the wild, making things even worse.
Well, the real worst-case scenario is that your JWT is out in the wild and still valid, then someone just changes your account details to their own and hijacks it from you without you knowing.
Obviously, letting people know that your email address has an account is not great, but it's no different than someone attempting to register a new account with your email and it saying "This email address has already been taken".
How do you go about creating a user with Knock? As I understand it, the method you're showing above is to sign in a user and create a token. How would my create User controller method sign in the new user and create their token?
Is there a example available which shows how the Access token can be dealt with on the client side.
I have built the API with user authentication via Knock.
I am now trying to build a seprate Rails app which would consume this API however I am lost as to how the token would be saved client side.
Hiyas i have try to use this tutorial for that i get the pro :) and is cool but i have a problem try to use in my actual project im using Mongoid and devise i get errir at try to use has_secure_password :( can i get some help please
Hi again i try to use normaly make a new project and only use a controller it make to my the token but at try to autentificate using the token i get 401
HTTP/1.1 401 Unauthorized, i detect the problem is Devise can i get help to make working using devise and dont get conflict ?
I was just going paste my solution to this here and I find the same one, haha.
Next I'll try to read first the comments, rather than searching on google, haha.
Looks like knock has an eager_load problem with Rails 6 & knock is no longer being maintained.
Yep, check out the JWT from scratch episode instead. That one will work just fine and you won't have to depend on other maintainers.
I will do that next - for better understanding indeed. I am mostly interested in the Devise JWT - since that is what I use most of the time anyway, but the series is interesting so I figured it can't hurt to debug a little.
Solution for Rails 6
To fix the autoloading problem on config and the error
(uninitialized constant Knock)while trying to use
change the line in:
config.load_defaults 6.0 and config.autoloader = :classic
To fix the problem
Can't verify CSRF token authenticity.
skip_before_action :verify_authenticity_tokenin the file:
so the controller needs to look like:
class Api::V1::UserTokenController < Knock::AuthTokenController skip_before_action :verify_authenticity_token def entity_name 'User' end end
AFTER these two fixes:
curl --data "auth[email][email protected]&auth[password]=*******" http://localhost:3000/api/v1/user_token
How do deal with token refesh?
Are you going to record something baout this?
I am getting this weird error where a HTML page is returned when the curl request for data is made and no JWT is seen.
Also, for curl -v status code is also 200 OK hence shows that no JWT is made
The knock gem GitHub page says: "This project is not being maintained and I don't recommend using it in its current form. As an alternative, I recommend using the jwt gem directly."
Could someone post an update in the comments at least showing how to "use the jwt gem directly" ?