ucd-library / csus-sp-2018-app

MIT License
1 stars 1 forks source link

Fin Authentication and Session Management #13

Open DerekMaggio opened 6 years ago

DerekMaggio commented 5 years ago

@jrmerz during our meeting tomorrow 10-30 I would like to develop requirements for authentication and session management

DerekMaggio commented 5 years ago
const api = require('@ucd-lib/fin-node-api');
const jwt = require('jsonwebtoken')

// I ran this command to create a user
// docker-compose exec basic-auth node service/cli create-user -u csus -p password -e s.project.csus@gmail.com

values = {
    username: 'csus',
    password: 'password',
    admin: 'false'
}

//This is the line from the .env file
// JWT_SECRET=lax

token = jwt.sign(values, 'lax')

config_vals = {
    host:'http://localhost:3000',
    jwt: token,
    username: 'csus',
    password: 'password'
}

api.setConfig(config_vals)

console.log(api.getConfig())

@jrmerz is this on the right track to setup the fin-node-api config?

DerekMaggio commented 5 years ago

@jrmerz just throwing another mention so you see the above comment.

jrmerz commented 5 years ago

Close, here is the server function that mints jwt tokens: https://github.com/UCDavisLibrary/fin-server/blob/master/node-utils/jwt.js#L51. Note the payload is just username and admin flag. Then you pass in the secret as well as additional TTL (time to live) and issuer values. The TTL and issuer are used to expire the token as well as verify who issued token.

And here are the params required for fin-node-api config: https://github.com/UCDavisLibrary/fin-server/blob/master/server/index.js#L20. basePath is almost always '/fcrepo/rest' and can be ignored. Host is required. Jwt is required. The api library will then be able to make requests as the minted JWT username until the TTL expires, then you need to mint a new JWT. The system does support refresh tokens, but I would ignore those for now.

Here are some quick samples. Note, path does NOT include /fcrepo/rest, this is added for you:

HEAD request:

let response = await api.head({path});

is this response path a rdf or binary container?

if( api.isRdfContainer(response) ) {
   // is rdf
}

get rdf as jsonld, check response status code

let response = await api.get({
  path,
  headers : {
     accept : api.RDF_FORMATS.JSON_LD
   }
});

if( !response.checkStatus(200) ) {
  // badness
}

// grab and parse json. the last property is the http response object from the last
// http request made, some calls from the library make multiple http requests.
let jsonld = JSON.parse(response.last.body);
DerekMaggio commented 5 years ago

Perfect thanks man! This is working so far. I really appreciate it!!!

DerekMaggio commented 5 years ago
const api = require('@ucd-lib/fin-node-api');
const jwt = require('jsonwebtoken')
const config = require('../config')

/*
     Not sure if this file is going to stay or not.
     I just want to get this process tracked by git before I forget how to do it.

     Created user 'csus' and set the as non-admin

     What is going to be done is the values JSON is going to be hashed with a secret that will be stored on
     our server and the UC Davis local instance. The result of this has is a JSON Web Token (jwt)

     This how we are going to provide user authentication.
*/

values = {
    username: 'csus',
    admin: 'false'
}

// Want the token to be good for 7 weeks so that way I don't have to worry about reissuing it.
// We are specifying the issuer for fin to validate against.
options = {
    expiresIn: '7w',
    issuer: config.jwt_issuer
}

token = jwt.sign(values, config.jwt_secret, options)

/*
    The required values to configure fin-node-api are host, basePath, and the jwt.

    Definitions:
        host: where the server is located at
        basePath: the path to the fin repo. (defaulted to /fcrepo/rest)
        jwt: your created JSON Web Token
*/

config_vals = {
    host:'http://localhost:3000',
    jwt: token,

}

api.setConfig(config_vals)

// Just specifying a path that I know exists
// path = 'collection/example_3-catalogs'

path = ''

let response = api.get({path});

// Returns a promise. Have to wait for the promise to resolve to get the value
response.then(function (result) {
    console.log(result)
})

@jrmerz I am trying to access the root of the LDP to see what different DAMS I have access to. For instance, users, and catalogs. Even though I am sending a validated token along I am getting a 403 error. What I do not understand is that I am able to access collection/example_3-catalogs.

The main reason that I am do this is I am trying to set up connecting users to the queries that they have sent. Am I going about doing this incorrectly?

jrmerz commented 5 years ago

Does csus have access to the root of the DAMS? by default the root is not publicly readable. You need to either give csus access to root or mint the token with admin=true.

Note, booleans are not strings:

values = {
    username: 'csus',
    admin: false
}

Pro tip, you can directly link to git branchs/commits via urls so you don't have to paste the entire files code: https://github.com/ucd-library/csus-sp-2018-app/blob/f20a957bf52aa7b58ac65b1f3af185d13a6520c3/middlewares/fin_communication_wrapper.js

You can even link to a line in a file (just click the line number): https://github.com/ucd-library/csus-sp-2018-app/blob/f20a957bf52aa7b58ac65b1f3af185d13a6520c3/middlewares/fin_communication_wrapper.js#L19 raw url looks like: https://github.com/ucd-library/csus-sp-2018-app/blob/f20a957bf52aa7b58ac65b1f3af185d13a6520c3/middlewares/fin_communication_wrapper.js#L19

DerekMaggio commented 5 years ago

@jrmerz I attempted your suggestion and I am still getting a 403 error. I am pretty stuck right now and need to get moving on sending our data to LDP in order to get current on our sprints.

jrmerz commented 5 years ago

Can you send over the full request you are making? Include headers so I can see the JWT token in use.

DerekMaggio commented 5 years ago

I am not actually using request to make the call. I am using fin-node-api. Do you want me to send to you the parameters I am passing to the api.get call?

jrmerz commented 5 years ago

Please. Include the JWT token as well

DerekMaggio commented 5 years ago

This is code I am using to mint my token and send the call. I left the requires out to condense down the message

values = {
    username: 'csus',
    admin: 'true'
}

options = {
    expiresIn: '7w',
    issuer: 'mylibrary.org'
}
let secret = 'lax';
token = jwt.sign(values, secret, options)

config_vals = {
    host:'http://localhost:3000',
    jwt: token,

}
api.setConfig(config_vals)
path = ''
let response = api.get({path});
response.then(function (result) {
    console.log(result)
})

Here is the response that I am getting

ApiResponse {
  httpStack: 
   [ IncomingMessage {
       _readableState: [Object],
       readable: false,
       domain: null,
       _events: [Object],
       _eventsCount: 4,
       _maxListeners: undefined,
       socket: [Object],
       connection: [Object],
       httpVersionMajor: 1,
       httpVersionMinor: 1,
       httpVersion: '1.1',
       complete: true,
       headers: [Object],
       rawHeaders: [Array],
       trailers: {},
       rawTrailers: [],
       upgrade: false,
       url: '',
       method: null,
       statusCode: 403,
       statusMessage: 'Forbidden',
       client: [Object],
       _consuming: true,
       _dumped: false,
       req: [Object],
       request: [Object],
       toJSON: [Function: responseToJSON],
       caseless: [Object],
       read: [Function],
       body: '<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n<title>Error 403 Forbidden</title>\n</head>\n<body><h2>HTTP ERROR 403</h2>\n<p>Problem accessing /fcrepo/rest. Reason:\n<pre>    Forbidden</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.6.v20170531</a><hr/>\n\n</body>\n</html>\n',
       finAuthenticated: true } ],
  last: 
   IncomingMessage {
     _readableState: 
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     domain: null,
     _events: 
      { end: [Array],
        close: [Array],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     connection: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers: 
      { 'x-powered-by': 'Express',
        connection: 'close',
        'cache-control': 'no-cache, no-store, must-revalidate',
        'content-type': 'text/html;charset=iso-8859-1',
        'content-length': '327',
        server: 'Jetty(9.4.6.v20170531)',
        expires: '0',
        pragma: 'no-cache',
        'set-cookie': [Array],
        date: 'Wed, 07 Nov 2018 17:54:57 GMT' },
     rawHeaders: 
      [ 'X-Powered-By',
        'Express',
        'connection',
        'close',
        'Cache-Control',
        'no-cache, no-store, must-revalidate',
        'content-type',
        'text/html;charset=iso-8859-1',
        'content-length',
        '327',
        'server',
        'Jetty(9.4.6.v20170531)',
        'Expires',
        '0',
        'Pragma',
        'no-cache',
        'set-cookie',
        'fin-sid=s%3A1fPXzrwaDK9YoQwFqKaACkWGlVE6F-Yj.b8MCB5fU64WTdJF%2BBHwQMg9SI4Cgd1%2B66Yj%2BN0%2BjfGw; Path=/; Expires=Wed, 14 Nov 2018 17:54:57 GMT; HttpOnly',
        'Date',
        'Wed, 07 Nov 2018 17:54:57 GMT' ],
     trailers: {},
     rawTrailers: [],
     upgrade: false,
     url: '',
     method: null,
     statusCode: 403,
     statusMessage: 'Forbidden',
     client: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     _consuming: true,
     _dumped: false,
     req: 
      ClientRequest {
        domain: null,
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        upgrading: false,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Object],
        connection: [Object],
        _header: 'GET /fcrepo/rest HTTP/1.1\r\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNzdXMiLCJhZG1pbiI6InRydWUiLCJpYXQiOjE1NDE2MTMyOTcsImV4cCI6MTU0NTg0Njg5NywiaXNzIjoibXlsaWJyYXJ5Lm9yZyJ9.8jwSif9fqL7FuFJppI-um_sUZYQ_m8uVwqDsG5GhG68\r\nCache-Control: no-cache\r\nUser-Agent: fin-node-api\r\nhost: localhost:3000\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Object],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path: '/fcrepo/rest',
        _ended: true,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        [Symbol(outHeadersKey)]: [Object] },
     request: 
      Request {
        domain: null,
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        method: 'GET',
        headers: [Object],
        uri: [Object],
        callback: [Function],
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Object],
        _auth: [Object],
        _oauth: [Object],
        _multipart: [Object],
        _redirect: [Object],
        _tunnel: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        pool: {},
        dests: [],
        __isRequestRequest: true,
        _callback: [Function],
        proxy: null,
        tunnel: false,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: '3000',
        host: 'localhost',
        path: '/fcrepo/rest',
        httpModule: [Object],
        agentClass: [Object],
        agent: [Object],
        _started: true,
        href: 'http://localhost:3000/fcrepo/rest',
        req: [Object],
        ntick: true,
        response: [Circular],
        originalHost: 'localhost:3000',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     read: [Function],
     body: '<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n<title>Error 403 Forbidden</title>\n</head>\n<body><h2>HTTP ERROR 403</h2>\n<p>Problem accessing /fcrepo/rest. Reason:\n<pre>    Forbidden</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.6.v20170531</a><hr/>\n\n</body>\n</html>\n',
     finAuthenticated: true },
  data: 
   IncomingMessage {
     _readableState: 
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: [Object],
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     domain: null,
     _events: 
      { end: [Array],
        close: [Array],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     connection: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers: 
      { 'x-powered-by': 'Express',
        connection: 'close',
        'cache-control': 'no-cache, no-store, must-revalidate',
        'content-type': 'text/html;charset=iso-8859-1',
        'content-length': '327',
        server: 'Jetty(9.4.6.v20170531)',
        expires: '0',
        pragma: 'no-cache',
        'set-cookie': [Array],
        date: 'Wed, 07 Nov 2018 17:54:57 GMT' },
     rawHeaders: 
      [ 'X-Powered-By',
        'Express',
        'connection',
        'close',
        'Cache-Control',
        'no-cache, no-store, must-revalidate',
        'content-type',
        'text/html;charset=iso-8859-1',
        'content-length',
        '327',
        'server',
        'Jetty(9.4.6.v20170531)',
        'Expires',
        '0',
        'Pragma',
        'no-cache',
        'set-cookie',
        'fin-sid=s%3A1fPXzrwaDK9YoQwFqKaACkWGlVE6F-Yj.b8MCB5fU64WTdJF%2BBHwQMg9SI4Cgd1%2B66Yj%2BN0%2BjfGw; Path=/; Expires=Wed, 14 Nov 2018 17:54:57 GMT; HttpOnly',
        'Date',
        'Wed, 07 Nov 2018 17:54:57 GMT' ],
     trailers: {},
     rawTrailers: [],
     upgrade: false,
     url: '',
     method: null,
     statusCode: 403,
     statusMessage: 'Forbidden',
     client: 
      Socket {
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'localhost',
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: [Object],
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: [Object],
        writable: false,
        allowHalfOpen: false,
        _bytesDispatched: 346,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: null,
        _server: null,
        parser: null,
        _httpMessage: [Object],
        read: [Function],
        _consuming: true,
        _idleNext: null,
        _idlePrev: null,
        _idleTimeout: -1,
        [Symbol(asyncId)]: 8,
        [Symbol(bytesRead)]: 778 },
     _consuming: true,
     _dumped: false,
     req: 
      ClientRequest {
        domain: null,
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        upgrading: false,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: false,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [Object],
        connection: [Object],
        _header: 'GET /fcrepo/rest HTTP/1.1\r\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImNzdXMiLCJhZG1pbiI6InRydWUiLCJpYXQiOjE1NDE2MTMyOTcsImV4cCI6MTU0NTg0Njg5NywiaXNzIjoibXlsaWJyYXJ5Lm9yZyJ9.8jwSif9fqL7FuFJppI-um_sUZYQ_m8uVwqDsG5GhG68\r\nCache-Control: no-cache\r\nUser-Agent: fin-node-api\r\nhost: localhost:3000\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Object],
        socketPath: undefined,
        timeout: undefined,
        method: 'GET',
        path: '/fcrepo/rest',
        _ended: true,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        [Symbol(outHeadersKey)]: [Object] },
     request: 
      Request {
        domain: null,
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        method: 'GET',
        headers: [Object],
        uri: [Object],
        callback: [Function],
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Object],
        _auth: [Object],
        _oauth: [Object],
        _multipart: [Object],
        _redirect: [Object],
        _tunnel: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        pool: {},
        dests: [],
        __isRequestRequest: true,
        _callback: [Function],
        proxy: null,
        tunnel: false,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: '3000',
        host: 'localhost',
        path: '/fcrepo/rest',
        httpModule: [Object],
        agentClass: [Object],
        agent: [Object],
        _started: true,
        href: 'http://localhost:3000/fcrepo/rest',
        req: [Object],
        ntick: true,
        response: [Circular],
        originalHost: 'localhost:3000',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     read: [Function],
     body: '<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>\n<title>Error 403 Forbidden</title>\n</head>\n<body><h2>HTTP ERROR 403</h2>\n<p>Problem accessing /fcrepo/rest. Reason:\n<pre>    Forbidden</pre></p><hr><a href="http://eclipse.org/jetty">Powered by Jetty:// 9.4.6.v20170531</a><hr/>\n\n</body>\n</html>\n',
     finAuthenticated: true },
  error: null }
jrmerz commented 5 years ago

You missed my note about Boolean values. The admin flag should not be a string.

DerekMaggio commented 5 years ago

@jrmerz I now have access to LDP and have connected our app to use the basic auth service. I am able to create users and login. I am able to see that the cookie has been set by the auth service. What I am confused about is the next step to creating different sessions for our application. Can you point me in the right direction please?

jrmerz commented 5 years ago

Great to hear! And happy to help on next steps, but can you elaborate on what you mean by:

What I am confused about is the next step to creating different sessions for our application?

DerekMaggio commented 5 years ago

So I am trying to make sure that we are allowing different sessions for different users.

So more than 1 user can access the app at once and their sessions will be completely separate

On Nov 16, 2018, at 8:06 AM, Justin Merz notifications@github.com wrote:

Great to hear! And happy to help on next steps, but can you elaborate on what you mean by:

What I am confused about is the next step to creating different sessions for our application?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub, or mute the thread.

DerekMaggio commented 5 years ago

@jmrez

I am also having trouble pushing data and creating collections in ldp.

Would you be able to meet sometime this coming week for me to pick your brain on a few things?

On Nov 16, 2018, at 8:06 AM, Justin Merz notifications@github.com wrote:

Great to hear! And happy to help on next steps, but can you elaborate on what you mean by:

What I am confused about is the next step to creating different sessions for our application?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub, or mute the thread.

jrmerz commented 5 years ago

@DerekMaggio Ya, your response to about sessions makes me think there is some badness in your setup.

I'm around Monday-Wednesday next week and my schedule is mostly open other than Monday morning. I can meetup online Mon/Tues, I could also come on campus on Wed (assuming things open up by then obviously) if you want to arrange that.

DerekMaggio commented 5 years ago

@jrmerz would a remote chat sometime Wednesday work for you? If we cannot get the questions answered tomorrow during our meeting?

jrmerz commented 5 years ago

Sure, time?

DerekMaggio commented 5 years ago

Does 9am work?

jrmerz commented 5 years ago

Yup, sounds good

DerekMaggio commented 5 years ago

@jrmerz Is there any prep work that you would suggest before the meeting? Any problems that you might suspect that you think would be easier for me to look into before the meeting?

jrmerz commented 5 years ago

The session is stored as a cookie, as you stated above. So to log a user out (or switch a user) you need to clear the cookie. This can be done by calling /auth/logout, which just clears the session cookie and removes the token and any associated session information stored in Redis server side. Thats it. To log a user in, you then call the login method again.

Cookies are stored in the browser and sent with every HTTP request. So multiple users should always be able to login via multiple browsers. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

Past that, I'm not sure what 'What I am confused about is the next step to creating different sessions for our application?' means, so not sure how to help. Can you elaborate?

DerekMaggio commented 5 years ago

@jrmerz From that, do I then need to implement something like express-session so my application knows that we are using different sessions?

On Nov 20, 2018, at 8:27 AM, Justin Merz notifications@github.com wrote:

The session is stored as a cookie, as you stated above. So to log a user out (or switch a user) you need to clear the cookie. This can be done by calling /auth/logout, which just clears the session cookie and removes the token and any associated session information stored in Redis server side. Thats it. To log a user in, you then call the login method again.

Cookies are stored in the browser and sent with every HTTP request. So multiple users should always be able to login via multiple browsers. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

Past that, I'm not sure what 'What I am confused about is the next step to creating different sessions for our application?' means, so not sure how to help. Can you elaborate?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.