Repository: frappe/frappe

Issue:
Google social login is failing with Invalid Token error every now and then.
<!--
Welcome to the Frappe Framework issue tracker! Before creating an issue, please heed the following:

1. This tracker should only be used to report bugs and request features / enhancements to Frappe
    - For questions and general support, use https://stackoverflow.com/questions/tagged/frappe
    - For documentation issues, refer to https://frappeframework.com/docs/user/en or the developer cheetsheet https://github.com/frappe/frappe/wiki/Developer-Cheatsheet
2. Use the search function before creating a new issue. Duplicates will be closed and directed to
   the original discussion.
3. When making a bug report, make sure you provide all required information. The easier it is for
   maintainers to reproduce, the faster it'll be fixed.
4. If you think you know what the reason for the bug is, share it with us. Maybe put in a PR 😉
-->

## Description of the issue

Social login with google fails every now and then with 'Invalid Token' error because of a token key missing in redis (actually expired).

Upon login page load there is a token key being set in redis cache with expiry as 120 seconds. Now if someone doesn't login in the said period since page load, it throws invalid token error even though login and handshakes all are correct.

This issue can be resolved if this token in redis cache (which is a random hash) is set during google login button click rather than during page load which is currently in get_context method of login.py file.


## Context information (for bug reports)

**Output of `bench version`**
```
erpnext 13.0.0-beta.14
frappe 13.0.0-beta.12
```

## Steps to reproduce the issue

1. Go to login page '/#login'
2. Leave it there (do nothing) for say 5 mins (actually > 2mins also should do)
3. Then try logging in using google login button.
4. It will throw 'Invalid Token' error with request as 'Invalid Request'

Sometimes this issue is also happening for every nth person randomly. But I could reproduce it consistently only through above steps.

### Observed result
Invalid token error

### Expected result
Should login and open desk page without issues.

### Stacktrace / full error message

```
Invalid Request: Invalid Token Error
```

## Additional information

OS version / distribution, `Frappe` install method, etc.

OS:
version-10 (buster)/ Debian.

Frappe:
erpnext 13.0.0-beta.14
frappe 13.0.0-beta.12




Discussion:
@nikhilponnuru , 

> Sometimes this issue is also happening for every nth person randomly. But I could reproduce it consistently only through above steps.

@nikhilponnuru , what do you mean by happening randomly? Currently token expires after 120 sec(2min) . Do you see `Invalid Token Error` happening with out waiting time in login page sometimes? 
@leela Yes. There were cases where people reported seeing this invalid token error even though they didn't wait for that 120 seconds. They came to the site, clicked on google login and this happend. Though number of such cases are low.

Ideally this setting of token expiry should be on login button click not on login page load.




Resolving patch:
diff --git a/frappe/utils/oauth.py b/frappe/utils/oauth.py
--- a/frappe/utils/oauth.py
+++ b/frappe/utils/oauth.py
@@ -64,8 +64,6 @@ def get_oauth2_authorize_url(provider, redirect_to):
 
 	state = { "site": frappe.utils.get_url(), "token": frappe.generate_hash(), "redirect_to": redirect_to 	}
 
-	frappe.cache().set_value("{0}:{1}".format(provider, state["token"]), True, expires_in_sec=120)
-
 	# relative to absolute url
 	data = {
 		"redirect_uri": get_redirect_uri(provider),
@@ -176,11 +174,6 @@ def login_oauth_user(data=None, provider=None, state=None, email_id=None, key=No
 		frappe.respond_as_web_page(_("Invalid Request"), _("Token is missing"), http_status_code=417)
 		return
 
-	token = frappe.cache().get_value("{0}:{1}".format(provider, state["token"]), expires=True)
-	if not token:
-		frappe.respond_as_web_page(_("Invalid Request"), _("Invalid Token"), http_status_code=417)
-		return
-
 	user = get_email(data)
 
 	if not user:
diff --git a/frappe/www/login.py b/frappe/www/login.py
--- a/frappe/www/login.py
+++ b/frappe/www/login.py
@@ -95,14 +95,6 @@ def login_via_frappe(code, state):
 def login_via_office365(code, state):
 	login_via_oauth2_id_token("office_365", code, state, decoder=decoder_compat)
 
-@frappe.whitelist(allow_guest=True)
-def login_oauth_user(data=None, provider=None, state=None, email_id=None, key=None, generate_login_token=False):
-	if not ((data and provider and state) or (email_id and key)):
-		frappe.respond_as_web_page(_("Invalid Request"), _("Missing parameters for login"), http_status_code=417)
-		return
-
-	_login_oauth_user(data, provider, state, email_id, key, generate_login_token)
-
 @frappe.whitelist(allow_guest=True)
 def login_via_token(login_token):
 	sid = frappe.cache().get_value("login_token:{0}".format(login_token), expires=True)


Test patch: