Get Django sessions on Node.js - django

I'm trying to add Node.js to my web application in Django to have real time.
I'm doing the functionality of "like" as in facebook, when users click "like" AJAX will post the ID of song to domain.com:3000 (Node.js server).
I have the user ID on a session variable, but i don't know how to access to this session variable from Node.js.
Here is my code:
Node.js
var express = require('express');
var app = express();
app.use(express.static('./public'));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.get('/', function(req, res){
res.send("ID user: " + req.session.user_id);
});
app.listen(3000);
console.log("Working under 3000")
Django
def auth(request):
if request.is_ajax() and request.method == 'POST':
email = request.POST.get('username', '')
password = request.POST.get('password', '')
autenti = JayapalBackend()
auth = autenti.authenticate(email, password)
if auth is not None:
id_usuario = Usuario.objects.get(email=email).getId()
request.session['user_id'] = id_usuario
return HttpResponse('1')
else:
return HttpResponse("-1")
else:
return HttpResponse("-1")
Thanks
EDITED:
I get this error:
TypeError: Cannot read property 'user_id' of undefined

Related

Angular + Django Backend. How to Log in base on user types in Django

I'm facing a problem on how to integrate user permission like if the is_superuser is False, then log in to Author component and if is_superuser is True, log in to Admin component in Angular. I hope someone can help.
What I want,
If the is_superuser is True in django, then log in to a Admin
component / admin dashboard
If the is_superuser is False in django, then log in to a Author
component / Author dashboard
class MyAuthToken(auth_views.ObtainAuthToken):
serializer_class = MyAuthTokenSerializer
#action(detail=True, methods=['POST'])
def post(self, request, *args, **kwargs):
response = super(MyAuthToken, self).post(request, *args, **kwargs)
token = Token.objects.get(key=response.data['token'])
user = CustomUser.objects.get(id=token.user_id)
users = json.dumps(UserSerializer(user).data)
id = json.loads(users)["id"]
email = json.loads(users)["email"]
is_superuser = json.loads(users)["is_superuser"]
return Response({'id': id, 'email': email, 'is_superuser': is_superuser,
'token': token.key})
finally solved my own problem. What I did was return a json response which will include the some user details to the front end. then call it on the front end.
Here's how I did it in my front end. I console log it to check the results
interface TokenObj {
id: number
email: string
is_superuser: boolean;
token: string;
}
_id: number;
_email: string;
_is_superuser: boolean;
_token: any;
mrToken: string;
loginUser() {
this.service.userLogin(this.authForm.value).subscribe(
(result: TokenObj) => {
this._token = this.cookieService.set('mr-token', result.token);
this._id = result.id
this._email = result.email
this._is_superuser = result.is_superuser
this._token = result.token
console.log("******** id " + this._id);
console.log("******** email " + this._email);
console.log("******** is_superuser " + this._is_superuser);
console.log("******** token " + this._token);
if (this._is_superuser === true && this._token){
this.router.navigateByUrl('/approuting');
}
else if (this._is_superuser === false && this._token){
this.router.navigateByUrl('/approuting/employee');
}
},
error => console.log(alert("wrong credentials"))
);
}
}
I really wanted to post my answer so I created a new account. I hope the other account can post answers soon. I also hope this will find beginner programmers who like me that is integrating angular and Django for a web development

testing stripe on-boarding django with mock

i am having trouble trying to mock test the on-boarding process of stripe connect. I am just learning how to use mock and i am struggling with the StripeAuthorizeCallbackView. the process is as follows: A user reaches the StripeAuthorizeView which sends them to the stripe api to sign up for an account. Once they successfully sign up for an account their redirected back to my platform and stripe sends a temporary code which i then send back to stripe with my api keys. Once i have sent the information back to stripe they then return me credentials for the user being the stripe_user_id.
Here is the two views in question:
import urllib
import requests
class StripeAuthorizeView(LoginRequiredMixin, View):
def get(self, request):
url = 'https://connect.stripe.com/express/oauth/authorize?'
user = self.request.user
if user.account_type == 'Business':
business_type = 'company'
else:
business_type = 'individual'
params = {
'response_type': 'code',
'scope': 'read_write',
'client_id': settings.STRIPE_CONNECT_CLIENT_ID,
'redirect_uri': f'http://127.0.0.1:8000/accounts/stripe/oauth/callback',
'stripe_user[email]' : user.email,
'stripe_user[business_type]' : business_type,
'stripe_user[url]' : 'http://127.0.0.1:8000/accounts/user/%s/' %user.pk,
}
url = f'{url}?{urllib.parse.urlencode(params)}'
return redirect(url)
lass StripeAuthorizeCallbackView(LoginRequiredMixin, View):
def get(self, request):
code = request.GET.get('code')
if code:
data = {
'client_secret': settings.STRIPE_SECRET_KEY,
'grant_type': 'authorization_code',
'client_id': settings.STRIPE_CONNECT_CLIENT_ID,
'code': code
}
url = 'https://connect.stripe.com/oauth/token'
resp = requests.post(url, params=data)
stripe_user_id = resp.json()['stripe_user_id']
stripe_access_token = resp.json()['access_token']
stripe_refresh_token = resp.json()['refresh_token']
user = self.request.user
user.stripe_access_token = stripe_access_token
user.stripe_user_id = stripe_user_id
user.stripe_refresh_token = stripe_refresh_token
user.save()
notify.send(sender=user, recipient=user,
verb='You have succesfully linked a stripe account. You can now take payments for sales.',
level='info')
redirect_url = reverse('account', kwargs={'pk': user.pk})
response = redirect(redirect_url)
return response
else:
user = self.request.user
notify.send(sender=user, recipient=user,
verb='Your attempt to link a stripe account failed. Please contact customer support.',
level='warning')
url = reverse('account', kwargs={'pk': user.pk})
response = redirect(url)
return response
I am not very worried about testing the StripeAuthorizeView a lot. I am more trying to figure out how to test the StripeAuthorizeCallbackView. All i can figure out is that i will need to mock both the code returned and then mock the following requests.post. This test is important to confirm my platform is linking the users credentials after the on-boarding process. Any help on this will be greatly appricated.
edit:
So far i have the following :
#classmethod
def setUpTestData(cls):
cls.test_user = User.objects.create_user(
password='test',
full_name='test name',
email='test#test.com',
address='1 test st',
suburb='test',
state='NSW',
post_code='2000',
contact_number='0433335333' )
#patch('requests.get')
def test_authorizecallback_creates_stripe_details(self, get_mock):
code = requests.get('code')
user = self.test_user
self.client.login(email='test#test.com', password='test')
mocked = ({'stripe_user_id' : '4444','stripe_access_token' : '2222',
'stripe_refresh_token' : '1111' })
with mock.patch('requests.post', mock.Mock(return_value=mocked)):
response = self.client.get('/accounts/stripe/oauth/callback/',
{'code' : '1234'})
self.assertEqual(user.stripe_access_token, '222')
message = list(response.context.get('messages'))[0]
however i keep getting:
File "C:\Users\typef\Desktop\Projects\python_env\fox-listed\Fox-Listed\fox-listed\user\views.py", line 142, in get
stripe_user_id = resp.json()['stripe_user_id']
AttributeError: 'dict' object has no attribute 'json'
the actual response that the StripeAuthorizeCallBackView gives is:
{'access_token': 'sk_test_1KyTG74Ouw65KYTR1O03WjNA00viNjcIfO', 'livemode': False, 'refresh_token': 'rt_H3Vrhd0XbSH7zbmqfDyMNwolgt1Gd7r4ESBDBr5a4VkCzTRT', 'token_type': 'bearer', 'stripe_publishable_key': 'pk_test_**********', 'stripe_user_id': 'acct_1GVOpAF7ag87i2I6', 'scope': 'express'}
Looks like i got it, if there is a flaw here let me know but here is what i have:
class TestStripeAuthorizeCallbackView:
#patch('user.views.requests')
def test_authorizecallback_creates_stripe_details(self, requests_mock):
json = { 'stripe_user_id' : '4444', 'access_token' : '2222', 'refresh_token' : '1111'}
requests_mock.post.return_value.json.return_value = json
user = mixer.blend('user.CustomUser', stripe_user_id=None, access_token=None, refresh_token=None)
req = RequestFactory().get('/', data={'code' : '1234'})
middleware = SessionMiddleware()
middleware.process_request(req)
req.session.save()
messages = FallbackStorage(req)
setattr(req, '_messages', messages)
req.user = user
resp = StripeAuthorizeCallbackView.as_view()(req)
assert resp.status_code == 302 ,'should redirect to success url'
assert user.stripe_user_id == '4444', 'should assign stripe_user_id to user'
assert user.stripe_access_token == '2222', 'should assign an access_token'
assert user.stripe_refresh_token == '1111', 'should assign a refresh_token'
What you're describing isn't mocking so much as it is end-to-end testing, connecting actual test accounts, which you can do.
As long as you're using a test client_id then when you are redirected to Stripe to create the account you can skip the form via a link and get directed back to your site with a real (test mode) oauth code.
Essentially you can set this up and actually go through the flow to create & connect new disposable test Stripe accounts.

Cookies works in Postman , but not in browser

I created a login API using Django rest framework and then used session auth.
When i sent request via Postman , i get csrftoken and sessionid cookies.
and i was able to access content on backend.
OK fine.
But when i built small login form html and called that API for logging in. It worked.
I see COOKIES IN RESPONSE BUT COOKIES ARE NOT SET IN CHROME BROWSER.
Under Storage section in dev tools cookies are empty.
when i tried to access content(other views/apis) , i was not able to..
I think its because of Cookies are not being stored in browser..
Been on this like 5 days. Please can Someone explain about cookies not being saved.?
View.py
class Login(APIView):
authentication_classes = [SessionAuthentication,]
def post(self, request, format=None):
username = request.POST.get("username", "")
print(request.session)
password = request.POST.get("password", "")
user = authenticate(request,username=username,password=password)
if user is not None:
login(request,user)
print(user)
return Response('Yes')
else :
return Response('No')
class List(APIView):
authentication_classes = [SessionAuthentication,]
permission_classes = [IsAuthenticated,]
def get(self, request, format=None):
return Response("Ark")
My Axios Request for login :
let s = this;
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Authorization", "Basic cjox");
myHeaders.append("Access-Control-Allow-Credentials","*");
var urlencoded = new URLSearchParams();
var requestOptions = {
method: 'POST',
credentials: 'same-origin',
headers: myHeaders,
body: urlencoded,
redirect: 'follow'
};
axios.post("http://127.0.0.1:8000/api/login/",urlencoded,{headers:myHeaders},{withCredentials: true})
.then(res=>{
console.log(res.headers);
})
My other request :
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/x-www-form-urlencoded");
myHeaders.append("Access-Control-Allow-Credentials","*");
var urlencoded = new URLSearchParams();
var requestOptions = {
method: 'GET',
credentials: 'same-origin',
headers: myHeaders,
redirect: 'follow'
};
axios.get("http://127.0.0.1:8000/api/d/",{headers:myHeaders},{withCredentials: true});

How to Sync Django HTTP Login Session with Websocket Session/Cookie?

I am using Django DjangoChannelsGraphqlWs which is Graphene version of Django Channels. (https://github.com/datadvance/DjangoChannelsGraphqlWs) It allows me to transfer data using graphql style. I wrote a login login on my mutation schema.
class Login(graphene.Mutation):
class Arguments:
email = graphene.String()
password = graphene.String()
ok = graphene.Boolean()
user = graphene.Field(UserType)
def mutate(root, info, email, password, **kwargs):
ok = False
user = authenticate(info.context, username=email, password=password)
if user is not None:
login(info.context, user)
update_or_create_user_login_info(info=info)
ok = True
return Login(ok=ok, user=user)
else:
return Login(ok=ok)
And I wrote my client side Websocket using Apollo-client like this:
class WebSocketService {
static instance = null;
callbacks = {};
static getInstance() {
if (!WebSocketService.instance)
WebSocketService.instance = new WebSocketService();
return WebSocketService.instance;
}
constructor() {
this.socketRef = null;
this.connect();
}
connect() {
const client = new SubscriptionClient(BASE_URL + '/graphql/', {
reconnect: true,
});
const link = new WebSocketLink(client);
const cache = new InMemoryCache();
this.socketRef = new ApolloClient({
link,
cache,
});
}
query = (query, variables={}, context={}, fetchPolicy='no-cache', errorPolicy='all') =>
this.socketRef.query({
query: gql`${query}`,
variables,
context,
fetchPolicy,
errorPolicy
})
mutate = (mutation, variables={}, context={}, fetchPolicy='no-cache', errorPolicy='all') =>
this.socketRef.mutate({
mutation: gql`${mutation}`,
variables,
context,
fetchPolicy,
errorPolicy
})
}
const WebSocketInstance = WebSocketService.getInstance();
export default WebSocketInstance;
Lastly, here is my consumer.
class MyGraphqlWsConsumer(channels_graphql_ws.GraphqlWsConsumer):
"""Channels WebSocket consumer which provides GraphQL API."""
schema = schema
send_keepalive_every = 60
I attempted to log in using the WebSocketInstance. However, Django's login function fails when I hand over info.context and authenticate(info.context, user) parameters. It throws error saying "types.SimpleNamespace' object has no attirbute 'META'". After stumbling upon with the error, I gave up with logging in with a websocket and decided to just use axios and normal http request.
But here is another issue. The session and cookies are not synced. When I use axios and normal http request, the login itself does work well, but websocket connection does not reflect the logged in session/cookies.
I found that it takes some time to reflect the change and it happens after disconnecting and reconnecting the websocket.
How should I sync the login information?
try overing the graphl_jwt
class ObtainJSONWebToken(graphql_jwt.JSONWebTokenMutation):
user = graphene.Field(UserType)
session = graphene.String()
#classmethod
def resolve(cls, root, info, **kwargs):
user=info.context.user
if user:
login(info.context,user)
session=info.context.session
session.save()
if session.session_key:
#print(session.session_key)
return cls(user=user,session=session.session_key)
else:
raise Exception('try it again')
in mutation
class Mutation(graphene.ObjectType):
token_auth=ObtainJSONWebToken.Field()

Why HttpResponseRedirect.set_cookie is not working when i use in django project?

When I use Google OAuth to verify my user, After verify is passed, I want to redirect to the page which user visit before authority, So I want to save the page path to user's cookie, so I implementation like this:
def get_login_resp(request, redirect):
print(redirect)
auth_url = "https://accounts.google.com/o/oauth2/auth?" + urlencode({
"client_id": GOOGLE_CLIENT_ID,
"response_type": "code",
"redirect_uri": make_redirect_url(request, redirect),
"scope": "profile email",
"max_auth_age": 0
})
resp = HttpResponseRedirect(auth_url)
max_age = 3600 * 24
expires = datetime.strftime(datetime.utcnow() + timedelta(seconds=max_age), "%a, %d-%b-%Y %H:%M:%S GMT")
print(expires)
resp.set_cookie('google_auth_redirect', redirect, max_age=max_age, expires=expires,
domain=LOGIN_COOKIE_DOMAIN, secure=True, httponly=True)
print(resp._headers)
print(resp.cookies)
return resp
ps: redirect is the page path which I want to save
But when request the login url with Postman, I can only see this headers:
response headers
And these cookies:
Cookies
So how can i do with this problem? There is not any error info for me.
Try every methods to find out what's wrong, But still failed.
So I try to run server on an other machine(a Linux server), it works!!!
BTW: My develop PC is Macbook Pro 15-inch, 2017 with macOS High Sierra 10.13.1
Update at 14/Jan/2020:
Didn't find the root cause, but I solved this issue by saving redirect_url to session data, in this solution you should check auth valid by using another request, then call google auth to reauth again, code like below:
class GoogleAuthView(RedirectView):
# google auth view
def get(self, request, *args, **kwargs):
# get redirect url from url params, frontend code should pass the param in request url
redirect_url = request.GET.get('redirect_url', None)
if redirect_url:
redirect_url = parse.unquote(redirect_url)
credentials = request.session.get("credentials", None)
if (not credentials) or ('expire_time' not in credentials) or (credentials['expire_time'] < time.time()):
request.session['redirect_url'] = redirect_url # if need google auth, save redirect url to session first
else:
if redirect_url:
return HttpResponseRedirect(redirect_url)
flow = google_auth_oauthlib.flow.Flow.from_client_config(
client_config=settings.GOOGLE_AUTH_CONFIG,
scopes=settings.GOOGLE_AUTH_SCOPES
)
flow.redirect_uri = settings.GOOGLE_AUTH_CONFIG['web']['redirect_uris'][0]
authorization_url, state = flow.authorization_url(
access_type='offline',
include_granted_scopes='true'
)
request.session['state'] = state
return HttpResponseRedirect(authorization_url)
class GoogleAuthCallBackView(BasicView):
# google callback view
def get(self, request, *args, **kwargs):
state = request.session.get('state')
flow = google_auth_oauthlib.flow.Flow.from_client_config(
client_config=settings.GOOGLE_AUTH_CONFIG,
scopes=settings.GOOGLE_AUTH_SCOPES,
state=state
)
flow.redirect_uri = settings.GOOGLE_AUTH_CONFIG['web']['redirect_uris'][0]
# get redirect url from session data if exists
redirect_url = request.session.get('redirect_url') or settings.ADMIN_LOGIN_REDIRECT_URL
response = HttpResponseRedirect(redirect_url)
try:
del request.session['redirect_url']
except KeyError:
logger.info('Delete `redirect_url` in session get KeyError.')
pass
try:
flow.fetch_token(authorization_response=request.build_absolute_uri())
except Exception as e:
logger.error(e.message)
return response
# save credentials to session
credentials = flow.credentials
request.session["credentials"] = {
'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes,
'expire_time': time.time() + TOKEN_EXPIRE_TIME,
}
profile_client = googleapiclient.discovery.build(
serviceName='oauth2',
version='v2',
credentials=credentials
)
profile = profile_client.userinfo().v2().me().get().execute()
email = profile['email']
user = user_manager.get_user_by_email(email)
if user:
user.username = profile['name'] # sync username from google
user.picture = profile['picture'] # sync avatar from google
user.save()
request.session["user"] = user.to_dict()
else:
return HttpResponseRedirect("/api/non_existent_user/") # show non-existent user
return response