Im trying to send a simple email to do the password recover of a user, the input is just a email to send the new password..
But i can't... i get this error
SMTPServerDisconnected: please run connect() first
I already tried a few examples, like, https://bitbucket.org/andialbrecht/appengine_emailbackends/overview, but i get the same error
I really need this, maybe someone can tell me how to use an alternative to code in my view to send an email...Also i changed the backend to
EMAIL_BACKEND = 'djangoappengine.mail.EmailBackend'
but nothing,i don't know how to use this backend anyway :(
Plz Help :(
maybe someone can tell me how to use an alternative to code in my view to send an email...
I can help with this, seeing as it seems that perhaps this repository you're trying to use is based on an earlier version of App Engine and is throwing the error due to a required code change somewhere in the library - either that or the fact that you changed the string from what the library recommends (your version: 'djangoappengine.mail.EmailBackend') to a string that seems to not be correct, as it's different to what the author of the repository directed you to use (their version: 'appengine_emailbackend.EmailBackend'), and this is causing trouble.
Whenever possible, I'd recommend seeing if there is an "app-engine-y" way to do something, before going to a third-party library or deploying a module somebody else wrote to hack in third-party capabilities, or looking for an advanced/experimental feature (for example, use Datastore first, rather than remotely connecting to a MySQL VM, unless you need MySQL). If you absolutely need that library, this is a different story, but if you just want to send emails, the Mail API is what you need. It's a convenient way to send emails on App Engine.
I'm going to assume in the following that you are storing your user's usernames and hashed passwords in custom-defined User-kind entities in your Datastore. If you have your users using simple OAuth to sign into your site, there is never any reason to "reset/recover password":
Create the <form action="/some/route" action="POST"> element on
the page where the user requests password recovery.
Put the code responsible for handling this form submission (they will input their email, or whatever account info they need for your code to find their User entity in the Datastore in a handler that will respond on that route.
In the handler, generate a unique token and store it in the Datastore. Send the token in the email that you generate and send using the Mail API (see the example code in the link to the docs I provided). This will allow your user to return to your site, authenticate with the token from the email, and then fill out a form to create a new password. You will then hash this password (with a salt) and store it in their User entity in your Datastore.
I'm skipping over the details of how to implement a "password recovery form", given what I said about OAuth and that you are probably really only concerned with how to send mail. In the email you send, for example, you can insert a hyperlink to your site with the token already inserted as a query param, so that the user doesn't have to copy and paste, etc.
Related
I am struggling to understand exactly how JWT-based authentication should be implemented in Django (I am using simplejwt). I am just a beginner, so please brace yourselves for some silly questions. The rest-framework-simplejwt documentation is very minimal and does not provide enough detail for a newbie like me.
path('token/obtain', jwt_views.TokenObtainPairView.as_view(), name='token_create'),
path('token/refresh', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
So, I've created the paths in my urls.py as suggested by the official documentation. Where do I go from here? I guess my confusion comes from the fact that I am not sure where exactly in the code I have to issue my tokens. Let's say, I am logging in the user. So, in order to obtain the token, do I have to send a request to the 'token_create' endpoint from inside my view? Or do I have to somehow indicate it in one of my serializers? What about the 'refresh_token' endpoint? Is there a specific method that I need to use?
Then, what do I do with the token once it has been issued? Clearly, I shouldn't save it in the database since it defeats the entire purpose of using JWTs in the first place. From my understanding, I should attach it to the headers so that the subsequent requests by the user contain the tokens in the headers.
The frontend will be written in ReactJS and will be on a separate server from my Django backend API, and the communication between the two will be configured through CORS.
In this case, how do I attach the token to the headers and make it so that the user's browser sends in the token with each request? Is there some sort of package that could be useful for that?
I think you just mixed everything up, I'm gonna explain everything however you may already know some stuff.
JWT simply is a way to authorize users, you usually create an endpoint to create a token for the users, this endpoint can be named login, create_token, 'generate_token', or anything! doesn't really matter!
However maybe if u use a specific library maybe it forces you to use a specific endpoint but in Flask it's really what you like.
This login (whatever you call it) endpoint will take a username and password and checks if it exists and it's correct, then generates a JWT with a library like PyJWT, You can configure the JWT to be expired in for example 20 mins or more, then you encrypt a dictionary(JSON?) which usually contains user_id which you query from the database. example of the JSON you provide to the user with:
{
"user_id": something,
"role": something,
...
}
Then it will be encrypted to a long string.
now when the user sends a request, he/she needs to have that long string as the Authorization header of the request.
In postman --> Authorizations, choose Bearer Authorization and then insert that long string.
We also give the user a refresh_token.
This is the example of the JSON you provide the user with when he/she calls the login endpoint:
{
token: some_long_string,
refresh_token: some_long_string,
}
So what is refresh Token?
it's just the token that when the main token expires instead of making the user enter username and password again, he just sends the refresh token we gave him while he called login.
One more point: This was the whole flow and logic you need to implement. Do it as you like, libraries or anything you like, doesn't really matter.
I've heard that MongoDB is very good Database, especially for placing large data inside, However i'm not sure how safe can it really be.
I'm not experienced at MongoDB, but before i choose, i want to know how safe it can be for important data.
So for example, if i specified uri, i would type this:
uri = "mongodb://test1:test1#ds051990.mongolab.com:51990/base1"
I'm trying to make a P2P text chat, It can be accessed on user's PC with root permissions, Whenever user registers, User's Latest IP, Username and will be added to database, as code was shown below.
But the "Hacker" would easily access it by simply getting into code, and viewing all the information, then he would read/write all the data inside.
What would be the best solution to prevent this issue? I think high-level Databases like MongoDB would have some-kind of protection against other users accessing it.
How can make sure only necessary users can access database and other users can't enter it by viewing uri variable?
If not is there ANY other way i can do it? So user can't access Database at all, But i would read and write files from database.
You have no easy way of hiding the credentials. Instead, create a user with the minimal required permissions in the database, and use these credentials in your distributed code.
If you are worried about the users being able to see plain-text IP addresses, you should hash and salt them before inserting them to the database.
We're using GAE Python and allow users to login using their existing Google accounts. The login code is straightforward:
def _require_login(self, target_url="/"):
if not self.user_bundle.user:
return self.redirect(
self.user_bundle.create_login_url(target_url),
abort=True
)
This creates a redirect to Google for the user to login, then upon successful login gets sent back to wherever they were originally trying to navigate.
The problem seems to be that if a user has more than a certain number of Google / GApps accounts logged in simultaneously (we're guessing 3 or more I can successfully reproduce it once I hit 5 accounts), they get an "Error 414" from Google:
My brief search on the error states that the URL is too long, since it's a GET request. Just about all of the advice states to use POST instead. The problem is, we're using Google's built-in create_login_url method, which, as far as I can tell, doesn't provide a way to specify POST instead of GET.
How can we fix this?
According to the Google Cloud Platform's Twitter account:
Unfortunately, only current fix is to logout of some accounts. >4 accounts logged in makes the URL too long (> 2048 bytes).
So now we're going to either make a pre-login page where it tells the user to log out of enough user accounts to meet the maximum number, or find an external library that allows us to let users log in without having to work around the limit.
I have a user input form here:
http://www.7bks.com/create (Google login required)
When you first create a list you are asked to create a public username. Unfortuantely currently there is no constraint to make this unique. I'm working on the code to enforce unique usernames at the moment and would like to know the best way to do it.
Tech details: appengine, python, webapp framework
What I'm planning is something like this:
first the /create form posts the data to /inputlist/ (this is the same as currently happens)
/inputlist/ queries the datastore for the given username. If it already exists then redirect back to /create
display the /create page with all the info previously but with an additional error message of "this username is already taken"
My question is:
Is this the best way of handling server side validation?
What's the best way of storing the list details while I verify and modify the username?
As I see it I have 3 options to store the list details but I'm not sure which is "best":
Store the list details in the session cookie (I am using GAEsessions for cookies)
Define a separate POST class for /create and post the list data back from /inputlist/ to the /create page (currently /create only has a GET class)
Store the list in the datastore, even though the username is non-unique.
Thank you very much for your help :)
I'm pretty new to python and coding in general so if I've missed something obvious my apologies.
Tom
PS - I'm sure I can eventually figure it out but I can't find any documentation on POSTing data using the webapp appengine framework which I'd need in order to do solution 2 above :s maybe you could point me in the right direction for that too? Thanks!
PPS - It's a little out of date now but you can see roughly how the /create and /inputlist/ code works at the moment here: 7bks.com Gist
I would use Ajax to do an initial validation. For example as soon as the user name input box loses focus I would in the background send a question to the server asking if the user name is free, and clearly signal the result of that to the user.
Having form validation done through ajax is a real user experience delight for the user if done correctly.
Of course before any of the data was saved I would definitely redo the validation server side to avoid request spoofing.
jQuery has a nice form validation plugin if you are interested. http://docs.jquery.com/Plugins/validation.
In my career, I've never gotten around having to validate server side as well as client side though.
About the storing of the list (before you persist it to the datastore). If you use ajax to validate the user name you could keep the other fields disabled until a valid user name is filled in. Don't allow the form to be posted with an invalid user name!
That would perhaps solve your problem for most cases. There is the remote possibility that someone else steals the user name while your first user is still filling in his list of books. If you want to solve that problem I suggest simply displaying the list as you got it from the request from the user. He just sent it to you, you don't have to save it anywhere else.
Can you use the django form validation functionality (which I think should just abstract all this away from you):
http://code.google.com/appengine/articles/djangoforms.html
Search in that page for "adding an item" - it handles errors automatically (which I think could include non-unique username).
Warning: also a beginner... :)
I'm working on an application that lets registered users create or upload content, and allows anonymous users to view that content and browse registered users' pages to find that content - this is very similar to how a site like Flickr, for example, allows people to browse its users' pages.
To do this, I need a way to identify the user in the anonymous HTTP GET request. A user should be able to type http://myapplication.com/browse/<userid>/<contentid> and get to the right page - should be unique, but mustn't be something like the user's email address, for privacy reasons.
Through Google App Engine, I can get the email address associated with the user, but like I said, I don't want to use that. I can have users of my application pick a unique user name when they register, but I would like to make that optional if at all possible, so that the registration process is as short as possible.
Another option is to generate some random cookie (a GUID?) during the registration process, and use that, I don't see an obvious way of guaranteeing uniqueness of such a cookie without a trip to the database.
Is there a way, given an App Engine user object, of getting a unique identifier for that object that can be used in this way?
I'm looking for a Python solution - I forgot that GAE also supports Java now. Still, I expect the techniques to be similar, regardless of the language.
Your timing is impeccable: Just yesterday, a new release of the SDK came out, with support for unique, permanent user IDs. They meet all the criteria you specified.
I think you should distinguish between two types of users:
1) users that have logged in via Google Accounts or that have already registered on your site with a non-google e-mail address
2) users that opened your site for the first time and are not logged in in any way
For the second case, I can see no other way than to generate some random string (e.g. via uuid.uuid4() or from this user's session cookie key), as an anonymous user does not carry any unique information with himself.
For users that are logged in, however, you already have a unique identifier -- their e-mail address. I agree with your privacy concerns -- you shouldn't use it as an identifier. Instead, how about generating a string that seems random, but is in fact generated from the e-mail address? Hashing functions are perfect for this purpose. Example:
>>> import hashlib
>>> email = 'user#host.com'
>>> salt = 'SomeLongStringThatWillBeAppendedToEachEmail'
>>> key = hashlib.sha1('%s$%s' % (email, salt)).hexdigest()
>>> print key
f6cd3459f9a39c97635c652884b3e328f05be0f7
As hashlib.sha1 is not a random function, but for given data returns always the same result, but it is proven to be practically irreversible, you can safely present the hashed key on the website without compromising user's e-mail address. Also, you can safely assume that no two hashes of distinct e-mails will be the same (they can be, but probability of it happening is very, very small). For more information on hashing functions, consult the Wikipedia entry.
Do you mean session cookies?
Try http://code.google.com/p/gaeutilities/
What DzinX said. The only way to create an opaque key that can be authenticated without a database roundtrip is using encryption or a cryptographic hash.
Give the user a random number and hash it or encrypt it with a private key. You still run the (tiny) risk of collisions, but you can avoid this by touching the database on key creation, changing the random number in case of a collision. Make sure the random number is cryptographic, and add a long server-side random number to prevent chosen plaintext attacks.
You'll end up with a token like the Google Docs key, basically a signature proving the user is authenticated, which can be verified without touching the database.
However, given the pricing of GAE and the speed of bigtable, you're probably better off using a session ID if you really can't use Google's own authentication.