How to authenticate user in socket io Python using JWT, - python

working on a project in socket io python and JWT for tokens. Can enyone please help on how to authenticate user using JWT in socketio python. And I am also getting error while generating JWT token. The error is on line
response_data['data']['token'] = token //response data is refered before assignment
How to solve this error and below is my code:
encrypted_password, col_name = DBHandler.SignIn(email)
if encrypted_password:
encrypted_password = encrypted_password[0][0].encode()
f = Fernet(key)
encrypted_password = f.decrypt(encrypted_password).decode()
if password == encrypted_password:
token = jwt.encode({'user': email, 'exp': datetime.utcnow() + timedelta(minutes=600)}, private_key,
algorithm='HS256')
print(token)
response_data['data']['token'] = token
return jsonify(response_data)
else:
print('Incorrect Password')
response_data = {
"status": "Error",
"message": "Error in Getting User from DB",
"data": {}
}
return make_response(jsonify(response_data), 400)

Related

Firebase & Pyrebase can't write to database with Authentication

I am farely new to Pyrebase and Firebase and I was wondering why this code isn't working.
I want to write to the realtime database, for that the rules are
{
"rules": {
"userdata": {
"$uid": {
".read": "$uid === auth.uid",
".write": "$uid === auth.uid"
}
}
}
}
And the python code is:
def login():
email = input("Enter email: ")
password = input("Enter password: ")
user = auth.sign_in_with_email_and_password(email, password)
user = auth.refresh(user['refreshToken'])
uid_variable = user['userId']
print(uid_variable)
print("Successfully logged in!")
data = {"test": "test"}
db.child("userdata").child(uid_variable).set(data)
But when it tries to write to the database it shows:
[Errno 401 Client Error: Unauthorized for url: https://xxxxxxxxxx-default-rtdb.europe-west1.firebasedatabase.app/userdata/xxxxxxxxxxxxxxxxxxxxxxxx.json] {
"error" : "Permission denied"
}
I don't seem to find any help anywhere so anything would be appreciated!
Depending on what you're using with your backend, this post on how to integrate Firebase Auth with a FastAPI backend using Pyrebase and Firebase Admin shows how you can create a login with Pyrebase using username and password
Based on the code here:
#app.post("/login", include_in_schema=False)
async def login(request: Request):
req_json = await request.json()
email = req_json['email']
password = req_json['password']
try:
user = pb.auth().sign_in_with_email_and_password(email, password)
jwt = user['idToken']
return JSONResponse(content={'token': jwt}, status_code=200)
except:
return HTTPException(detail={'message': 'There was an error logging in'}, status_code=400)
I believe you need to call the auth() function with the pyrebase object you created.

How to use 3-legged OAuth in Tweepy with Twitter API v2 to read protected Tweets?

I am trying to access protected Tweets from Twitter handles using Tweepy and Twitter API v2. To do this I know I have to use 3-legged OAuth. I have done it and successfully generated an access token and access token secret. But with those access keys I am not able to see the protected Tweets of my own protected account when I am authorizing with the same account.
Does anyone know what I am doing wrong here?
This is a login.py file with the authorization function
#!/usr/bin/env python
import tweepy
def authrize():
CONSUMER_KEY = "XXXXXXXXXXXxx"
CONSUMER_SECRET = "XXXXXXXXXXXXXXXXx"
BEARER_TOKEN = "XXXXXXXXXXXXXXXX"
auth = tweepy.OAuth1UserHandler(CONSUMER_KEY, CONSUMER_SECRET,callback="oob")
print(auth.get_authorization_url())
verifier = input("Input PIN: ")
ACCESS_TOKEN, ACCESS_TOKEN_SECRET = auth.get_access_token(verifier)
print(ACCESS_TOKEN,"******",ACCESS_TOKEN_SECRET)
return (CONSUMER_KEY,CONSUMER_SECRET,BEARER_TOKEN,ACCESS_TOKEN,ACCESS_TOKEN_SECRET)
and my tweepy code app.py is as follows
import tweepy
import login
def get_client(CONSUMER_KEY,CONSUMER_SECRET,BEARER_TOKEN,ACCESS_TOKEN,ACCESS_TOKEN_SECRET):
client = tweepy.Client(bearer_token=BEARER_TOKEN,
consumer_key=CONSUMER_KEY,
consumer_secret=CONSUMER_SECRET,
access_token=ACCESS_TOKEN,
access_token_secret=ACCESS_TOKEN_SECRET, wait_on_rate_limit=True)
return client
def get_user_id(username):
user = client.get_user(username=username)
return user.data.id
def pagination(user_id):
responses = tweepy.Paginator(client.get_users_tweets, user_id,
exclude='replies,retweets',
max_results=100,
expansions='referenced_tweets.id',
tweet_fields=['created_at', 'public_metrics', 'entities'])
return responses
def get_original_tweets(user_id):
tweet_list = []
responses = pagination(user_id)
for response in responses:
if response.data ==None:
continue
else:
for tweets in response.data:
tweet_list.append([tweets.text,
tweets['public_metrics']['like_count'],
tweets['public_metrics']['retweet_count'],
tweets['created_at'].date()])
return tweet_list
def user_details(username):
user = {}
user_response = client.get_user(username=username, user_fields=['public_metrics', 'description', 'url'])
user_metrics = user_response.data['public_metrics']
user['description'] = user_response.data['description']
user['followers'] = user_metrics['followers_count']
user['following'] = user_metrics['following_count']
return user
keys = login.authrize()
client = get_client(*keys)
username = input("Username:")
userid = get_user_id(username)
print(user_details(username))
print(get_original_tweets(userid))
By default, Client.get_users_tweets uses your bearer token rather than OAuth 1.0a User Context to authenticate. You need to set the user_auth parameter to True.

Twitter V2 API POST /2/tweets 403 Forbidden

I am trying to make a bot, which posts tweets.
Since my developer account is only essential, I am restricted to V2 API. At first, this is the example from github i used for posting a tweet: https://github.com/twitterdev/Twitter-API-v2-sample-code/blob/main/Manage-Tweets/create_tweet.py
consumer_key = "somekey"
consumer_secret = "somesecret"
payload = {"text": "Hello world!"}
request_token_url = "https://api.twitter.com/oauth/request_token"
oauth = OAuth1Session(consumer_key, client_secret=consumer_secret)
try:
fetch_response = oauth.fetch_request_token(request_token_url)
except ValueError:
print(
"There may have been an issue with the consumer_key or consumer_secret you entered."
)
resource_owner_key = fetch_response.get("oauth_token")
resource_owner_secret = fetch_response.get("oauth_token_secret")
print("Got OAuth token: %s" % resource_owner_key)
print("Got OAuth token secret: %s" % resource_owner_secret)
# Get authorization
base_authorization_url = "https://api.twitter.com/oauth/authorize"
authorization_url = oauth.authorization_url(base_authorization_url)
print("Please go here and authorize: %s" % authorization_url)
verifier = input("Paste the PIN here: ")
# Get the access token
access_token_url = "https://api.twitter.com/oauth/access_token"
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=resource_owner_key,
resource_owner_secret=resource_owner_secret,
verifier=verifier,
)
oauth_tokens = oauth.fetch_access_token(access_token_url)
access_token = oauth_tokens["oauth_token"]
access_token_secret = oauth_tokens["oauth_token_secret"]
print("Got OAuth token: %s" % access_token)
print("Got OAuth token: %s" % access_token_secret)
# Make the request
oauth = OAuth1Session(
consumer_key,
client_secret=consumer_secret,
resource_owner_key=access_token,
resource_owner_secret=access_token_secret,
)
# Making the request
response = oauth.post(
"https://api.twitter.com/2/tweets",
json=payload,
)
if response.status_code != 201:
raise Exception(
"Request returned an error: {} {}".format(response.status_code, response.text)
)
print("Response code: {}".format(response.status_code))
# Saving the response as JSON
json_response = response.json()
print(json.dumps(json_response, indent=4, sort_keys=True))
The user flow is the following. It seems OAuth has to be used, therefore, you have to get a 6 digit number and enter it in the terminal to get the access token:
Got OAuth token: #######
Got OAuth token secret: #######
Please go here and authorize: https://api.twitter.com/oauth/authorize?oauth_token=####
Paste the PIN here: ######
Got OAuth token: ########################################
Got OAuth token: ###############################
It's all working till the last step: actually posting the tweet with JSON. There, I get the following error:
Request returned an error: 403 {"title":"Forbidden","detail":"Forbidden","type":"about:blank","status":403}
What can I do? I simply want to post a tweet using Twitter V2 API, nothing more. Most tutorial use the old V1 or V1.1 api, which isn't helpful.
Edit: It seems to have to do something with the authentification being only read only: Twitter new API Essential access
Ran into the same issue and I needed to add oauth_callback and x_auth_access_type to the request_token request:
https://github.com/twitterdev/Twitter-API-v2-sample-code/blob/main/Manage-Tweets/create_tweet.py#L16
request_token_url = "https://api.twitter.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write"
Source: https://developer.twitter.com/en/docs/authentication/api-reference/request_token
(credit to zmoon - https://github.com/twitterdev/Twitter-API-v2-sample-code/issues/73)

401 UNAUTHORIZED status when attempting login from client side to backend flask api

I am trying to login from my website developed in Angular to the back end flask API, The backend uses bcrypt for encoding and pymongo for interacting with a MongoDB. In postman, the login endpoint works fine but when an attempt to log in on the client side is made I receive a 401: UNAUTHORIZED ERROR. Can someone advise what the issue is/where I am going wrong?
The login function on the client side:
onLogin() {
let postData = new FormData();
postData.append('username', this.loginForm.get('username').value);
postData.append('password', this.loginForm.get('password').value);
this.http.post('http://localhost:5000/api/v1.0/login', postData)
.subscribe((_response: any) => {
console.log(this.loginForm.value);
this.loginForm.reset();
})
}
The login endpoint in backend:
app = Flask(__name__)
CORS(app)
#app.route('/api/v1.0/login', methods=['POST'])
def login():
auth = request.authorization
if auth:
user = users.find_one({'username': auth.username})
if user is not None:
if bcrypt.checkpw(bytes(auth.password, 'utf-8'),
user["password"]):
token = jwt.encode( \
{'user' : auth.username,
'admin': user["admin"],
'exp' : datetime.datetime.utcnow() + \
datetime.timedelta(minutes=30)
}, app.config['SECRET_KEY'])
return make_response(jsonify( \
{'token':token.decode('UTF-8')}), 200)
else:
return make_response(jsonify( \
{'message':'Bad password'}), 401)
else:
return make_response(jsonify( \
{'message':'Bad username'}), 401)
In order to use request.authorization you need to send the credentials in the Authorization-header. Try this on the client:
onLogin() {
const usn = this.loginForm.get('username').value;
const pwd = this.loginForm.get('password').value;
this.http.post('http://localhost:5000/api/v1.0/login', null, {
headers: new HttpHeaders({
Authorization: `Basic ${btoa(`${usn}:${pwd}`)}`
})
}).subscribe((_response: any) => {
console.log(_response);
});
}
As a sidenote; the credentials can be easily decoded by using atob(), so make sure you are using a secure connection (HTTPS) when not on localhost.

trying to forward request with chalice

im trying to build a simple api+lambda with chalice which can receive a POST request and then forward it to another API while adding some authentication. when i run my chalice code locally i can send a request and print the payload which i sent inside chalice console yet i cannot forward my request. i don't get back any errors or other print statements which i have in my code. i don't know where else to look for more answers so im asking here.
from chalice import Chalice
import requests
app = Chalice(app_name='redirect_url')
app.debug = True
TOKEN_URL = "https://redirect.com/v0/token"
USERNAME = 'email#email.com'
PASSWORD = 'Password01021'
#app.route('/redirect_url', methods=['POST'])
def get_payload():
update_payload = app.current_request.json_body
print(update_payload)
def fetch_auth_token():
username = USERNAME
password = PASSWORD
data = {
"grant_type": "password",
"username": username,
"password": password
}
response = requests.post(TOKEN_URL, data=data)
token = response.json()
print(token)
IF I send a request to the endpoint (http://127.0.0.1:8000/redirect_url) I see my request printed inside chalice logs, but i don't see the token request.
I would appreciate any help
This is a bit old, but I thought I would answer it for the community for those new to Chalice.
You are expecting to fire the function without calling it. It should be:
from chalice import Chalice
import requests
app = Chalice(app_name='redirect_url')
app.debug = True
TOKEN_URL = "https://redirect.com/v0/token"
USERNAME = 'email#email.com'
PASSWORD = 'Password01021'
#app.route('/redirect_url', methods=['POST'])
def get_payload():
update_payload = app.current_request.json_body
APIresponse = fetch_auth_token()
print(APIresponse) ## If you want to show it right before the update_payload
print(update_payload)
def fetch_auth_token():
username = USERNAME
password = PASSWORD
data = {
"grant_type": "password",
"username": username,
"password": password
}
response = requests.post(TOKEN_URL, data=data)
return response.json()

Categories

Resources