refresh Directline token after it got expired

风格不统一 提交于 2021-01-01 02:50:06

问题


I'm applying a token based authentication to bot webchat along with the chat being persisted but facing an issue after the token got expired. Unable to connect to bot.

At first I'm generating a token and refreshing for 15 mins and every thing working fine till then. But, when user went offline with no internet connectivity, suppose for around 6-7 hours, due to offline the refresh token post call don't happen and there will be an expired token in the session storage. later than he wanted to chat with the same conversation he did before. but was going to FailedToConnect or ExpiredToken issue. As the token got expired due to inactivity unable to connect to bot again.

My main intention is how to connect user with the previous converstion.

Thanks in advance.

 (async function() {
    'use strict';
    const {
            hooks: { usePostActivity },
            hooks: { useDirection },
            ReactWebChat
    } = window.WebChat;
    
     let { token, conversation_Id } = sessionStorage;
    if ( !token ) {
                    const res = await fetch( 'https:/localhost/api/generateToken', { method: 'POST' } );
                    const { token: directLineToken, conversationId: conversationId } = await res.json();
                    sessionStorage[ 'token' ] = directLineToken;
                    sessionStorage[ 'conversation_Id' ] = conversationId;
                    token = directLineToken;
                    conversation_Id = conversationId;
                    }
                    
    if (token) {
        await setInterval(async () => {
        var myHeaders = new Headers();
        myHeaders.append("Authorization","Bearer "+ sessionStorage[ 'token' ]);
        let res = await fetch( 'https://directline.botframework.com/v3/directline/tokens/refresh', {
                                method: 'POST', 
                                headers: myHeaders,
                                });
        const { token: directLineToken, conversationId } = await res.json();
            sessionStorage[ 'token' ] = directLineToken;
            sessionStorage[ 'conversation_Id' ] = conversationId;
            token = directLineToken;
            conversation_Id = conversationId;
        }, 1000*60*15)}
        
                        
    
    
    const  store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
    if(action.payload && action.payload.directLine) {
        const subscription = action.payload.directLine.connectionStatus$.subscribe({
                error: error => console.log( error ),
                next: value => {
                        if ( value === 0 ) {console.log('Uninitialized')} 
                        else if ( value === 1 ) {console.log('Connecting')} 
                        else if ( value === 2 ) {console.log('Online')}
                        else if  ( value === 3 ) {console.log('Expire Token')}
                        else if ( value === 4 ) {console.log('FailedToConnect')}
                        else if ( value === 5 ) {console.log('Ended')}
                }
            });
        }
     if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
        dispatch({
                type: 'WEB_CHAT/SEND_EVENT',
                payload: {
                    name: 'Welcome',
                    value: { language: window.navigator.language }
                    }
                });
            }
            
    
    if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
                action = window.simpleUpdateIn(action, ['payload', 'activity', 'channelData', 'CustomChannel'], () =>"webchat");
                }
    
        return next(action);
    });
    
    
   const  botconnection = createDirectLine( {token,webSockets: true,watermark: "0" });
    
    window.ReactDOM.render(
    <ReactWebChat directLine={botconnection}
                  store={store}
        />,
        document.getElementById('webchat'));
        document.querySelector('#webchat > *').focus();
        })().catch(err => console.error(err));

回答1:


Unfortunately, once a token is expired there is no way to obtain a refreshed token in order to continue a conversation. The original token must still be valid when requesting a refreshed token.


Regarding maintaining a connection, there's no great option, but here is an idea that may be worth trying:

  • Create a service that, when a token is generated, it is sent to this service along with the user's online status.
  • The service would manage the token refreshes and would return the refreshed token to the original client to be consumed.
  • If a user goes offline, the call to return the refreshed token would fail, the service updates the user's online status, and follows some condition on when to stop refreshing (e.g. after 4 hours).
  • If a user comes back online, state is again updated, the refreshed token is consumed, and the conversation continues.

Hope of help!



来源:https://stackoverflow.com/questions/64806603/refresh-directline-token-after-it-got-expired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!