my token sends user_id How I can get it by localStorage in Angular? - django

I need help trying to figure it out, i am using django as backend and Angular as frontend.
My django backend pass a token so it can be acessed in frontend by login.
login.ts
onLogin() {
this.service.loginUser(this.input).subscribe(
response => {
console.log(response)
this.jwttoken.setToken(response['token']);
this.jwttoken.getItem(response);
this.router.navigate(['dashboard']);
},
error => {
console.log('error', error);
}
i save it in a localstorage that can be acessed on my service
jwttoken service
jwtToken : string
decodedToken: {[key: string]: string}
public storage: Storage;
constructor() {
this.storage = window.localStorage;
}
setToken(token: string){
if (token) {
this.jwtToken = token;
}
}
getItem(key: string) {
if(this.storage){
localStorage.setItem('token',(key));
}
return null;
}
i need to have my user id that i can see on my web browser console.
{"token":"[object Object]","d34330659cba7cf64e8414f83aa6522f55b0f978":"d34330659cba7cf64e8414f83aa6522f55b0f978","[object Object]":"{"token":"d34330659cba7cf64e8414f83aa6522f55b0f978","user_id":1,"email":"admin#admin.com"}"}
this is where i need to access my user id, so i can send it to my html file
export class RegularComponent implements OnInit {
patient_code: any;
number_tumor: any;
tumor_size: any;
tumor_volume: any;
biopsy_date: any;
hp_lote_number: any;
closeResult: string;
userlists: any;
user_id: any;
constructor(private service: SharedService, private modalService: NgbModal, private jwtstorage: JWTTokenServiceService) { }
localstorage = JSON.stringify(this.jwtstorage.storage).replace(/\\/g, "");
ngOnInit() {
// this.getUserlist();
console.log(this.localstorage);
}
// getUserlist() {
// let observable = this.service.getUsersList();
// observable.subscribe((data) => { this.userlists = data; console.log(data); return data; }); }
open(content) {
this.modalService.open(content,{ariaLabelledBy: 'modal-basic-title', size: 'lg'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}
I searched all around, and I can't figure it out. Could you explain to me how I can do this?
I just need the user_id of that string that cames from the localstorage. Thank you.

Related

hapi authentication strategy karma test with sinon with async function

I am trying to test the authentication scheme with hapi server. I have two helper function within the same file where I put my authentication scheme. I want to test when this successfully authenticate the user. But in my test case I always get 401 which is the unauthenicated message.
export const hasLegitItemUser = async (request, email, id) => {
const {
status,
payload: {users}
} = await svc.getRel(request, email);
if (status !== STATUS.OK) {
return false;
}
return users.includes(user)
};
export const getUser = async request => {
const token = request.state._token;
const res = await svc.validateToken({request, token});
const {
userInfo: {email}
} = res;
const id = extractId(request.path);
const isLetgitUser = await hasLegitItemUser(
request,
email,
id
);
res.isLegitUser = isLegitUser;
return res;
};
const scheme = (server, options) => {
server.state("my_sso", options.cookie);
server.ext("onPostAuth", (request, h) => {
return h.continue;
});
return {
async authenticate(request, h) {
try {
const {
tokenValid,
isLegitUser,
userInfo
} = await getUser(request);
if (tokenValid && isLegitUser) {
request.state["SSO"] = {
TOKEN: request.state._token
};
return h.authenticated({
credentials: {
userInfo
}
});
} else {
throw Boom.unauthorized(null,"my_auth");
}
} catch (err) {
throw Boom.unauthorized(null, "my_auth");
}
}
};
};
My Test file:
import Hapi from "hapi";
import sinon from "sinon";
import auth, * as authHelpers from "server/auth";
import {expect} from "chai";
import pcSvc from "server/plugins/services/pc-svc";
describe("Authentication Plugin", () => {
const sandbox = sinon.createSandbox();
const server = new Hapi.Server();
const authHandler = request => ({
credentials: request.auth.credentials,
artifacts: "boom"
});
before(() => {
server.register({
plugin: auth,
});
const route = ["/mypage/{id}/home"];
route.forEach(path => {
server.route({
method: "GET",
path,
options: {
auth: auth,
handler:{}
}
});
});
});
afterEach(() => {
sandbox.restore();
});
it("should authorize user if it is a validated user", async () => {
sandbox
.stub(authHelpers, "getUser")
.withArgs(request)
.resolves({
tokenValid: true,
isLegitUser: true,
userInfo: {}
});
return server
.inject({
method: "GET",
url:
"/mypage/888/home"
})
.then(res => {
expect(res.statusCode).to.equal(200);
expect(res.result).to.eql({
userInfo: {
email: "abc#gmail.com",
rlUserId: "abc",
userId: "abc#gmail.com"
}
});
});
});
});
I always get the 401 error for unauthenticated. It seems like my "getUser" function in my test is not triggering for some reason, it goes straight to the throw statement in the catch phase in my code. Please help.

How to work with JWT with Django and Redux

So I've recently learned about JWT authentication using Django Rest Framework and now, I would like to use it. Setting things up with DRF was easy, but now I'm facing a problem : I have no idea how to consume the given tokens ( access and refresh ) with redux. I also have no idea how to retrieve a user based on the given tokens.
Here is what I have for the moment.
My actions :
import axios from 'axios';
import {
LOGIN_STARTED,
LOGIN_SUCCESS,
LOGIN_FAILURE,
} from './types.js';
const loginStarted = () => ({
type: LOGIN_STARTED,
})
const loginFailure = error => ({
type: LOGIN_FAILURE,
payload: {
error: error
}
})
const loginSuccess = (access_token, refresh_token) => ({
type: LOGIN_SUCCESS,
payload: {
access_token: access_token,
refresh_token : refresh_token
}
})
export const authLogin = (username, password) => dispatch => {
dispatch(loginStarted);
axios.post("http://127.0.0.1:8000/api/token/", {
username: username,
password: password
})
.then( res => {
console.log(res.data);
dispatch(loginSuccess(res.data))
})
.catch( err => {
console.log(err);
dispatch(loginFailure(err.data));
})
}
And my reducer looks like this :
import {
LOGIN_STARTED,
LOGIN_SUCCESS,
LOGIN_FAILURE,
} from '../actions/types.js';
const initialstate = {
access: undefined,
refresh: undefined,
error: {}
}
export default function(state=initialstate, action){
switch (action.type) {
case LOGIN_SUCCESS:
return {
...state,
access: action.type.access_token,
refresh: action.type.refresh_token,
}
case LOGIN_FAILURE:
return {
...state,
error: action.payload.error
}
default:
return state;
}
}
Thank you !

Getting access to apolloClient within getInitialProps through SSR

I was hoping to get information to populate through SSR before the page loads. I've been following this example https://github.com/zeit/next.js/tree/canary/examples/with-apollo-auth/pages but been noticing the apolloClient doesn't exist within getInitialProps.
My withAuth.js
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { ApolloProvider } from 'react-apollo';
import PropTypes from 'prop-types';
import Head from 'next/head';
import Cookies from 'js-cookie';
import fetch from 'isomorphic-unfetch';
export const withApollo = (PageComponent, { ssr = true } = {}) => {
const WithApollo = ({ apolloClient, apolloState, ...pageProps }) => {
const client = apolloClient || initApolloClient(apolloState, { getToken });
return (
<ApolloProvider client={client}>
<PageComponent {...pageProps} />
</ApolloProvider>
);
};
if (process.env.NODE_ENV !== 'production') {
// Find correct display name
const displayName = PageComponent.displayName || PageComponent.name || 'Component';
// Warn if old way of installing apollo is used
if (displayName === 'App') {
console.warn('This withApollo HOC only works with PageComponents.');
}
// Set correct display name for devtools
WithApollo.displayName = `withApollo(${displayName})`;
// Add some prop types
WithApollo.propTypes = {
// Used for getDataFromTree rendering
apolloClient: PropTypes.object,
// Used for client/server rendering
apolloState: PropTypes.object
};
}
if (ssr || PageComponent.getInitialProps) {
WithApollo.getInitialProps = async (ctx) => {
const { AppTree } = ctx;
console.log(AppTree);
// Run all GraphQL queries in the component tree
// and extract the resulting data
const apolloClient = (ctx.apolloClient = initApolloClient(
{},
{
getToken: () => getToken(ctx.req)
}
));
const pageProps = PageComponent.getInitialProps ? await PageComponent.getInitialProps(ctx) : {};
// Only on the server
if (typeof window === 'undefined') {
// When redirecting, the response is finished.
// No point in continuing to render
if (ctx.res && ctx.res.finished) {
return {};
}
if (ssr) {
try {
// Run all GraphQL queries
console.log('trying');
const { getDataFromTree } = await import('#apollo/react-ssr');
await getDataFromTree(
<AppTree
pageProps={{
...pageProps,
apolloClient
}}
/>
);
} catch (error) {
// Prevent Apollo Client GraphQL errors from crashing SSR.
// Handle them in components via the data.error prop:
// https://www.apollographql.com/docs/react/api/react-apollo.html#graphql-query-data-error
console.error('Error while running `getDataFromTree`', error);
}
}
// getDataFromTree does not call componentWillUnmount
// head side effect therefore need to be cleared manually
Head.rewind();
}
// Extract query data from the Apollo store
const apolloState = apolloClient.cache.extract();
return {
...pageProps,
apolloState
};
};
}
return WithApollo;
};
let apolloClient = null;
/**
* Always creates a new apollo client on the server
* Creates or reuses apollo client in the browser.
*/
const initApolloClient = (...args) => {
// Make sure to create a new client for every server-side request so that data
// isn't shared between connections (which would be bad)
if (typeof window === 'undefined') {
return createApolloClient(...args);
}
// Reuse client on the client-side
if (!apolloClient) {
apolloClient = createApolloClient(...args);
}
return apolloClient;
};
const createApolloClient = (initialState = {}, { getToken }) => {
let fetchOptions = {};
const HTTP_ENDPOINT = 'http://localhost:4000/api';
const httpLink = createHttpLink({
uri: HTTP_ENDPOINT,
credentials: 'same-origin',
fetch,
fetchOptions
});
const authLink = setContext((request, { headers }) => {
const token = getToken();
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : ''
}
};
});
return new ApolloClient({
ssrMode: typeof window === 'undefined', // Disables forceFetch on the server (so queries are only run once)
link: authLink.concat(httpLink),
cache: new InMemoryCache().restore(initialState)
});
};
const getToken = () => {
return Cookies.get('token');
};
I'm using it as a HOC in my _app.js file and been trying to get access to the apolloClient in my Signin component hoping to do a check if a person is logged in, in order to redirect them (also would like to know in order to make the navbar dynamic)
Thank you for the help on this one
Try the following code and now you should be able to access apolloClient within getInitialProps.
const apolloClient = (ctx.ctx.apolloClient = initApolloClient({}, {
getToken: () => getToken(ctx.req)}));
I think you just missed one thing i.e. to return the apolloClient while returning the PageProps and ApolloCache when SSR is true.
// Extract query data from the Apollo store
const apolloState = apolloClient.cache.extract();
return {
...pageProps,
apolloState,
// To get access to client while in SSR
apolloClient
};

Why is User.Identity.IsAuthenticated == false when called via CORS

Why is User.Identity.IsAuthenticated == false when called via CORS, but true when called via same domain?
I have a working asp.net core 2 cookieauth app that is CORS enabled.
When I call;
api/Identity/establish-session
an AUTHCOOKIE gets dropped in both
CORS and local ajax calls.
Conversely when I call
api/Identity/sign-out
The AUTHCOOKIE gets removed. All good so far.
After a successful establish-session, when I call the following;
api/Identity/check-authentication
User.Identity.IsAuthenticated == false when called via CORS, but User.Identity.IsAuthenticated == true when called from the same domain.
I don't know if this is because of how I call it in javascript or if I have something configured wrong on the asp.net app. I thought I just had to have credentials: 'include' set in my fetch call?
[Produces("application/json")]
[Route("api/Identity")]
public class IdentityController : Controller
{
[HttpPost]
[AllowAnonymous]
[Route("establish-session")]
public async Task EstablishAuthenticatedSession(string username, string password)
{
var properties = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTime.UtcNow.AddHours(1)
};
var claims = new[] {new Claim("name", username), new Claim(ClaimTypes.Role, "User")};
var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
await
HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(identity),
properties);
}
[HttpGet]
[AllowAnonymous]
[Route("sign-out")]
public async Task Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
}
[HttpGet]
[AllowAnonymous]
[Route("check-authentication")]
public async Task<bool> CheckAuthentication()
{
return User.Identity.IsAuthenticated;
}
}
Here is my javascript snippets;
establishAuthenticatedSession(){
let self = this;
var model = this.get();
console.log(model);
var url = "https://localhost:44310/api/Identity/establish-session?username=herb&password=1234";
fetch(url,
{
credentials: 'include',
headers: { 'Content-Type': 'text/plain' },
method: 'POST'
})
.then(function (res) {
console.log(res);
self.set({ establishSession:{ message:"Success" }});
}).catch(function(error) {
self.set({ establishSession:{ message:error.message }});
console.log('There has been a problem with your fetch operation: ' + error.message);
});
},
signOut(){
let self = this;
var model = this.get();
console.log(model);
var url = "https://localhost:44310/api/Identity/sign-out";
fetch(url,
{
credentials: 'include',
headers: { 'Content-Type': 'text/plain' },
method: 'GET'
})
.then(function (res) {
console.log(res);
self.set({ signoutResult:{ message:"Success" }});
}).catch(function(error) {
self.set({ signoutResult:{ message:error.message }});
console.log('There has been a problem with your fetch operation: ' + error.message);
});
},
checkAuthenticatedSession(){
let self = this;
var model = this.get();
console.log(model);
var url = "https://localhost:44310/api/Identity/check-authentication";
fetch(url,
{
credentials: 'include',
method: 'GET',
headers: { 'Content-Type': 'text/plain' }
})
.then(res => res.text())
.then(function (res) {
console.log(res);
self.set({ checkAuthenticatedSession:{ message:res }});
})
.catch(function(error) {
self.set({ checkAuthenticatedSession:{ message:error.message }});
console.log('There has been a problem with your fetch operation: ' + error.message);
});
}
This is my CORS setup;
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
So it turns out that the cookie needs to be set as SameSiteMode.None. The hint I got was that that ARRAfinity cookie from azure as set to non and it was being sent where mine was not.
In my app I had to set it as follows;
public class Startup
{
...
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
...
services.AddAuthentication(sharedOptions =>
{
sharedOptions.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
// sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(
CookieAuthenticationDefaults.AuthenticationScheme,
options =>
{
options.LoginPath = "/Account/LogIn"; ;
options.AccessDeniedPath = new PathString("/account/login");
options.Cookie.Name = "AUTHCOOKIE";
options.ExpireTimeSpan = new TimeSpan(365, 0, 0, 0);
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.Cookie.SameSite = SameSiteMode.None;
}
);
...
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
var cookiePolicyOptions = new CookiePolicyOptions
{
Secure = CookieSecurePolicy.SameAsRequest,
MinimumSameSitePolicy = SameSiteMode.None
};
app.UseCookiePolicy(cookiePolicyOptions);
...
}
}

Angular 2: BehaviorSubject/Subject does not work outside constructor

Hi I need pass the data from one component to another, for this I am using the class BehavorSubject(I tried too with Subject class, but doesnt works for me). This is my code:
Home page has a filter, and when is selected a filter, it called the service and it service should change a variable of homePage
HomePage.ts
#Component({
providers: [PatientService],
})
export class HomePage {
subscription: Subscription;
constructor( public auth: AuthService,
public patientService: PatientService) {
this.subscription = this.patientService.nameGiven.subscribe(
nameGiven => {
this.patientsByElement = nameGiven.toString();
});
------ more code---
}
Filtro.ts
export class FiltroPage {
showFilter(filter : FiltroT): void{
... code ...
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.PatientService.getPatientsByTags(this.token,this.filterSelected);
} , 1000);
}
}
patient-service.ts
import { Subject } from 'rxjs/Subject';
import { Observable ,BehaviorSubject } from 'rxjs/Rx';
#Injectable()
export class PatientService {
nameSource = new BehaviorSubject("asd");
nameGiven = this.nameSource.asObservable();
this.nameSource.next('hi!!!'); //**it works but only in the constructor**
this.nameGiven.subscribe(()=>{
console.log("it changed");
});
getPatientsByTags(token: String, tags: Array<string>){
return new Promise(resolve => {
this.http.get(ConnectionParams.DevEnv + ProceduresNames.TagsByPatient + ProceduresNames.TagIdEtiqueta + tags, options)
.map(res => res.json())
.subscribe(data => {
if(data.data.poAnicuRegistros){
console.log("here")
this.nameSource.next('hi TON :/'); // <-- ***here is the problem. It doesnt work***
}
else
console.log("XX");
resolve( this.data);
});
});
}
}
Finally i didn't use the BehaviorSubject/Subject, i pass the data from the filter to Homepage of this way :
HomePage.ts
public popoverCtrl: PopoverController
//code ...
showFilter(myEvent) {
let popover = this.popoverCtrl.create(FiltroPage, {
showConfirm: (x) => {
//do something with the data received from the filter
}
});
popover.present({
ev: myEvent
});
}
Filter.ts
//code...
params: NavParams;
showConfirm() {// function that return the data to homePage
this.params.get('showConfirm')(this.patientsBytag);
}