I have the Vue app and the Django rest framework api separately.
One on localhost:8080 (vue app) and the rest api on localhost:8000.
So, I created an APIView that is supposed to log the user in when they make a post request:
class LoginUserAPIView(APIView):
permission_classes = () # login should be accessed by anyone, no restrictions.
def post(self, request, format=None):
username = request.data['username']
password = request.data['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
user = UserSerializer(user)
return Response({'success': 'Logged in', 'user': user.data})
return Response({'wrong': 'username or password not correct, try again'}, status=status.HTTP_401_UNAUTHORIZED)
And I was trying to get the user session from django with axios:
login() {
this.isLoading = true;
return axios({
method: 'post',
url: 'http://localhost:8000/api/login_user',
data: {
username: this.name,
password: this.password
},
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
this.$store.commit('loginAuth', true); // setting isAuth to true in vuex store.
this.$store.commit('setUser', response.data.user); // to access the user object since I don't use django templates
this.$router.push({name: 'page'}); // redirect to random test page that requires authorization so I can see if everything went fine.
})
.catch(err => {
console.error(err);
if (err.response.status == 401) {
alert(err.response.data.wrong);
this.isLoading = false;
}
})
but I was naive and I thought this would work, so when I checked the vue app for any cookies or sessions, nothing.
How could I set user session for a separate vue app?
Thanks in advance, I apologize for my lack of knowledge.
Related
So, I'm having a SPA which has Okta implemented for authentication. According to the Okta policy that is set up in place, the user(s) log in with credentials (email and password) and then are prompted to validate with a magic link or code (both sent to their primary email address). I'm trying to get around this and programmatically login through API
What I've tried so far:
a POST Request to the /api/v1/authn with the username and password (which returns a session token)
then a GET request to /oauth2/default/v1/authorize with the clientID,sessionToken,redirectUri,scope which should return the access and id tokens from my understanding...
This last request just redirect back to the login page.
Cypress.Commands.add('oktaLogin', () => {
const optionsSessionToken = {
method: 'POST',
url: `https://${Cypress.env('okta_domain')}/api/v1/authn`,
body: {
username: Cypress.env('okta_username'),
password: Cypress.env('okta_password'),
options: {
warnBeforePasswordExpired: 'true'
}
}
}
cy.request(optionsSessionToken).then(response => {
const sessionToken = response.body.sessionToken;
const qs = {
client_id: Cypress.env('okta_clientid'),
redirect_uri: `https://${Cypress.env('baseURL')}/callback`,
code_challenge_method: 'S256',
responseType: ['id_token','token'],
scope: ['openid', 'profile', 'email'],
sessionToken: sessionToken,
}
cy.request({
method: 'GET',
url: `https://${Cypress.env('okta_domain')}/oauth2/default/v1/authorize`,
form: true,
followRedirect: true,
qs: qs
}).then(response2 => {
//tokens should be available here?
cy.log(response2.body)}) //returns HTML back to login.
});
})
Using dj-rest-auth for user auth and registration on my react app.
Got login and logout to work using api endpoints in the docs.
Failing to register a user, getting HTTP bad request 400. Reading on the web, explains that there's something wrong with my request but cannot figure what.
EDIT: Tried insomina to simulate POST registration response and got error on a Django's side:
ConnectionRefusedError at /api/dj-rest-auth/registration/
[Errno 61] Connection refused
register.js
fetch('/api/dj-rest-auth/registration/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
user: 'alalala',
password1: '1234',
password2: '1234',
email: 'ala#gmail.com',
})
})
.then(res => {
res.json()
})
settings.py
SITE_ID = 1
CORS_ORIGIN_ALLOW_ALL = True
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
]
}
REST_AUTH_REGISTER_SERIALIZERS = {
'REGISTER_SERIALIZER': 'api.serializers.CustomRegisterSerializer'
}
INSTALLED_APPS = [
#local
'api',
# 3'rd party apps
'rest_framework',
'corsheaders',
'rest_framework.authtoken',
'dj_rest_auth',
'allauth',
'allauth.account',
'allauth.socialaccount',
'dj_rest_auth.registration',
# added django but it disable admin login logout pages
'django.contrib.sites',
# django default...
]
The issue was in the settings, in config of drf auth, in this case it would work with:
ACCOUNT_USERNAME_REQUIRED = True
ACCOUNT_EMAIL_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = 'none'
ACCOUNT_AUTHENTICATION_METHOD = 'username'
I am developing a web application using a React frontend and a Node.js backend. The frontend sends a POST request to the backend using Axios like this:
Register.js
...
handleSubmit = (e) => {
e.preventDefault();
const { email, password, name, dateofbirth } = this.state;
const user = { email, password, name, dateofbirth };
const url = "http://localhost:9000/register";
axios
.post(url, user, {
headers: {
"Content-Type": "application/json",
},
})
.then((response) => console.log(response))
.catch((error) => {
console.error("You have made a big error. " + error);
console.log(user);
});
};
...
While the backend receives the request like this:
./routes/register.js
...
router.post("/register", async (req, res) => {
console.log("Inside Home Login");
res.writeHead(200, {
"Content-Type": "application/json",
});
console.log("Users : ", JSON.stringify(users));
res.end(JSON.stringify(users));
})
...
However I get the error "POST http://localhost:9000/register 404 (Not Found)" upon trying to send anything.
My guess would be that you are routing in your index.js. If you can provide a code sample to figure it out.
If so, the thing is defining a routing like,
app.use('/register', yourImportedVariable);
does define a route at http://localhost:9000/register.
So, if in your routes/register.js file you define a GET endpoint with '/register' your front-end call must be http://localhost:9000/register/register
To fix it, either rename your route as '/', or fix your front-end call with the above url.
I am very new to the Google OAUth2.0 authentication and thus my question sounds like dumb. However, I am stuck with this problem quite a time and need your input to solve it.
I was integrating the Globus login within my app. Globus login using Google OAuth-2 protocol for authentication. According to the Globus Auth developer guide, I successfully redirect the app to their authorization service, the user can put their credential to authenticate, and the app receives the code returned from the Globus Auth server upon successful authentication. Next step is sending the code to the Token endpoint to get the access token. I used the following code:
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let tokenUri = encodeURIComponent(payload.redirect_uri);
let client_id = 'out app client id'
let client_secret = 'client secret generated for authentication'
let cred = btoa(client_secret);
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: tokenUri,
client_id: client_id
}),
{
headers:{
Authorization: 'Basic '+ cred,
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I am getting 401 {"error":"invalid_client"} code for this post request from the server. What am I missing?
N.B: I have tried without client secret, client id, not encoding redirect URL. No luck so far>
I would really appreciate your effort if you show me some light. Thanks for your time.
====Edited====
The error from the console at the browser is attached
I solved the problem. I had to put the client secret at the body of the post request. The following code resolves my problem.
var querystring = require('querystring');
export const logInGlobus = (payload) => {
let client_id = 'app client id'
let client_secret = 'client secret generated for authentication'
return axios.post('https://auth.globus.org/v2/oauth2/token',
querystring.stringify({
grant_type: 'authorization_code',
code: payload.code,
redirect_uri: payload.redirect_uri,
client_id: client_id,
client_secret: client_secret
}),
{
headers:{
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return{
res: response,
success: true
}
})
.catch(err => {
return{
res: err,
success: false
}
})
}
I'm developing the application with react js and redux. For backend i used java to create api's. So far i have created three services, login, signup, listing. I have used jwt token for listing service to secure the incformation. I have set jwt token expiration time is 10 mins in backend. Each 10 mins the jwt token will get expired and for new token i need to login again. This is what i have done in backend.
I have integrated those services in my react with redux concept. The problem which i'm getting is, each i need to go login screen for new token. I want this to be happen in background. How to do with redux?
export function handleResponse(response) {
if (response.ok) {
return response.json();
}
// If invalid jwt token the page will get redirect to login.
if (response.status === 401) {
localStorage.clear();
alert('Session expired!');
location.href = '/login';
}
}
export function loginAction(data) {
const resObject = {
username: data.username,
password: data.password,
};
return dispatch =>
fetch(`/login`, {
method: 'post',
body: JSON.stringify(resObject),
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${basicAuth.authSecret}`,
},
})
.then(handleResponse)
.then(res => dispatch(loginUser(res)));
}