You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, Crow itself doesn't handle Authentication, Although it's worth mentioning that HTTP Authentication is built on top of Headers, cookies, and request bodies. All of which Crow does handle.
You could find a good example for authentication handling (using Bearer Tokens) using Crow in my REST API called Forest (I use Gitlab for my personal projects). You can find the Authentication handling mainly in token.cpp, I just put Token::verifyToken at the top of any handler that requires authentication.
You can ignore anything database related (or replace with your own implementation). the idea is to take what's after "Bearer" and compare it.
For basic authentication. you can use the same method (replacing Bearer with Basic). You'll just need to decode the Base64 characters. and then handle the Username and Password separately.
for automatically enforcing authentication on every route?
This is specifically what I didn't want, I couldn't find a way to selectively run the middleware (see #45) which is why I resorted to putting Token::verifyToken only in the route I wanted Authentication to run in.
that holds a session_hash, user id and valid time (so that the server can invalidate the session), and any other data you need.
Then you may create a class called Sessions
#ifndef _SESSIONS_HPP_
#define_SESSIONS_HPP_
#include<mutex>
#include<unordered_map>
#include<chrono>
#include<utility>
#include<tuple>
#include<string>
#include"Session.hpp"classSessionsfinal
{
private:
{session_hash, SessionObject}
std::unordered_map<std::string, Session> sessions;
std::shared_mutex mSharedMutex;
//{email, UserObject}
std::unordered_map<std::string, User> users;
//insert a session into the unordered_map
std::string insert(const std::string & email, const std::uint32_t user_id, std::uint32_t valid_time_in_seconds = 900)
{
const std::string session_hash = some_random_secure_hash_function();
std::lock_guard<std::shared_mutex> lock(mSharedMutex);
sessions.insert({session_hash, Session(session_hash, user_id, valid_time_in_seconds)});
return session_hash;
}
public:
std::string create_session(const std::string & email, const std::string & password)
{
constauto user_find = users.find_user(email);
if(user_find == users.end()) //could not find the user associated with this emailreturnstd::string("");
//User object need to have the 'validate_user' function to hash it and compare itconstbool valid_user = user_find.second->validate_user(email, password);
if(!valid_user) //if not valid, no session hash for youreturnstd::string("");
constauto & user = user_find.second;
const std::uint32_t & user_id = user.id();
//same password, create session and return session_hashreturninsert(email, user_id);
}
//try to find the session and validate it (calculate time)boolvalidate_session(const std::string & session_hash)
{
constauto session_find = sessions.find(session_hash);
{
std::shared_lock<std::shared_mutex> lock(mSharedMutex);
if(session_find == sessions.end()) //session does not exists, not validreturnfalse;
}
//test if validif(session_find->second.valid())
returntrue; //is valid!!!//if it's not valid, destroy session and returns falsedestroy_session(session_hash);
returnfalse;
}
voiddestroy_session(const std::string & session_hash)
{
std::lock_guard<std::shared_mutex> lock(mSharedMutex);
sessions.erase(session_hash);
}
};
#endif// !_SESSIONS_HPP_
this should give you a nice start if you are willing to go with it. it's super fast and simple, you only need to sync it with a Database of your choice if you want it, and load from it afterwards
This page is referenced in the doc so now I have a class Session and a class Sessions and ... next ? what append ?
It's not clear at all what should be done to have a simple server with basic authentication. Can you push a complete working example ?
Something very simple with an helloworld displayed only if the user enter a static user+password for example.
Thanks for the help
PS : my context is : I have an existing small POC implementation in nodejs with ejs and basic auth with a login page, all together with bootstrap. node is convenient for the POC in my use case, but not for production. I'm looking for an equivalent and probably Crow is a good candidate but still need to confirm this scenario is possible.
@joelguittet Hi and sorry for being late to respond, things have been a little hectic with the 1.0 release.
The scenario you're mentioning (a login page and basic auth) is very much possible with Crow. You probably won't need to use sessions and can instead give the client a token in a cookie and use that to authenticate.
While I can make an example web page with what you need, but like I said the 1.0 release is taking much of my time. I'll still do my best to give you an example ASAP.
I would also appreciate it if you could open a separate issue for making an HTTP Auth with a webpage example so that it doesn't get lost since this issue is closed.
No problem, it's good to see the project is maintained and 1.0 is coming :-)
Thanks a lot to confirm the scenario is possible, this make me confident to use the project and start prototyping something.
No emergency on the example I understand you have a lot of work actually, I open a separated issue to keep trace of this request.
Hello,
I did authentication in my project using the Access Token approach as given in the official docs, and it is working fine. But
Is there any way I can use OAuth or OAuth2 in CrowCPP?
The user will not need to remember another password and can use their existing Google or some other account to log in to the app.
If someone has implemented this, can you please share any docs or code?
Activity
The-EDev commentedon Jun 9, 2021
Hi, Crow itself doesn't handle Authentication, Although it's worth mentioning that HTTP Authentication is built on top of Headers, cookies, and request bodies. All of which Crow does handle.
You could find a good example for authentication handling (using Bearer Tokens) using Crow in my REST API called Forest (I use Gitlab for my personal projects). You can find the Authentication handling mainly in
token.cpp, I just putToken::verifyTokenat the top of any handler that requires authentication.You can ignore anything database related (or replace with your own implementation). the idea is to take what's after "Bearer" and compare it.
For basic authentication. you can use the same method (replacing
BearerwithBasic). You'll just need to decode the Base64 characters. and then handle the Username and Password separately.The-EDev commentedon Jun 9, 2021
Let me know if this answers your question. If it does not, feel free to ask further and I'll help out as much as I can.
jessehl commentedon Jun 10, 2021
@The-EDev: you wrote "I just put
Token::verifyTokenat the top of any handler that requires authentication.".Wouldn't you suggest the use of Middleware (as documented here) for automatically enforcing authentication on every route?
The-EDev commentedon Jun 10, 2021
This is specifically what I didn't want, I couldn't find a way to selectively run the middleware (see #45) which is why I resorted to putting
Token::verifyTokenonly in the route I wanted Authentication to run in.ArthoPacini commentedon Jun 14, 2021
For Sessions you could create a Class called Session
that holds a session_hash, user id and valid time (so that the server can invalidate the session), and any other data you need.
Then you may create a class called Sessions
this should give you a nice start if you are willing to go with it. it's super fast and simple, you only need to sync it with a Database of your choice if you want it, and load from it afterwards
The-EDev commentedon Jun 14, 2021
Closing this for lack of response. Please reopen if you feel the question was not answered properly.
joelguittet commentedon Mar 27, 2022
@The-EDev hello,
This page is referenced in the doc so now I have a class Session and a class Sessions and ... next ? what append ?
It's not clear at all what should be done to have a simple server with basic authentication. Can you push a complete working example ?
Something very simple with an helloworld displayed only if the user enter a static user+password for example.
Thanks for the help
PS : my context is : I have an existing small POC implementation in nodejs with ejs and basic auth with a login page, all together with bootstrap. node is convenient for the POC in my use case, but not for production. I'm looking for an equivalent and probably Crow is a good candidate but still need to confirm this scenario is possible.
The-EDev commentedon Mar 29, 2022
@joelguittet Hi and sorry for being late to respond, things have been a little hectic with the 1.0 release.
The scenario you're mentioning (a login page and basic auth) is very much possible with Crow. You probably won't need to use sessions and can instead give the client a token in a cookie and use that to authenticate.
While I can make an example web page with what you need, but like I said the 1.0 release is taking much of my time. I'll still do my best to give you an example ASAP.
I would also appreciate it if you could open a separate issue for making an HTTP Auth with a webpage example so that it doesn't get lost since this issue is closed.
joelguittet commentedon Mar 30, 2022
Hello @The-EDev
No problem, it's good to see the project is maintained and 1.0 is coming :-)
Thanks a lot to confirm the scenario is possible, this make me confident to use the project and start prototyping something.
No emergency on the example I understand you have a lot of work actually, I open a separated issue to keep trace of this request.
Sincerely,
Joel
Akhil-Sharma-26 commentedon Jan 17, 2025
Hello,
I did authentication in my project using the Access Token approach as given in the official docs, and it is working fine. But
Is there any way I can use
OAuthorOAuth2in CrowCPP?The user will not need to remember another password and can use their existing Google or some other account to log in to the app.
If someone has implemented this, can you please share any docs or code?