쿠키 문자열에서 사용 가능한 JavaScript로

17019 단어 es6javascript

배경



안녕하세요, 이것은 일부 개발자에게 도움이 되기를 바라는 약간 심도 있는 게시물이 될 것입니다.

우리는 OAuth를 사용하고 있으며 프런트 엔드에서 세션 관리를 사용하는 방법 중 하나는 각 액세스 토큰 및 새로 고침 토큰 만료 날짜의 쿠키를 제공하는 것입니다.

가정



나는 독자가 .split, .map 및 .reduce 배열 방법 사용에 대해 잘 알고 있다고 가정합니다.

문제



백엔드는 Ruby on Rails를 사용하여 구축되었으며 응답 쿠키가 설정되었을 때 직면한 문제는 다음과 같습니다.
  • 프런트엔드에 대해 여러 쿠키가 저장됨
  • 액세스 토큰 만료 및 새로 고침 토큰 만료가 모두 인코딩된 문자열에 Ruby 해시로 저장됩니다.

  • // document.cookie
    'FLIPPER_ID=flipper_on; token_info=%7B%3Aaccess_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A11%3A58.265440745+UTC+%2B00%3A00%2C+%3Arefresh_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A36%3A58.147084176+UTC+%2B00%3A00%7D'
    


    요구 사항



    여기에서 세션 관리가 예상대로 작동하는지 확인하기 위한 몇 가지 요구 사항이 있었습니다.
  • 액세스 토큰 및 갱신 토큰 만료가 모두 있는 개체
  • JavaScript 날짜를 사용할 수 있는 만료일이 있음

  • 쿠키 개체 만들기의 1부




    const oAuthCookieObject = document.cookie
      // Creates an array of each cookie
      .split(';')
      // Maps the cookies to <key>=<value> pairs
      .map(cookie => cookie.split('='))
      /*
       Reduces it down to a single object of our access token and 
       refresh tokens by checking if our cookieKey includes the
       'info_token' value we are looking for
      */
      .reduce((_, [cookieKey, cookieValue]) => ({
        ...(cookieKey.includes('info_token') && {                
         ...formatOurCookie(decodeURIComponent(cookieValue))
        })
      }), {});
    


    파트 1 고장



    1) document.cookie에서 변수를 생성합니다.

    2) 각 쿠키 문자열을 분할합니다.

    // original string
    'FLIPPER_ID=flipper_on; info_token='
    // after .split
    ['FLIPPER_ID=flipper_on', 'info_token=%7B%3Aaccess_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A11%3A58.265440745+UTC+%2B00%3A00%2C+%3Arefresh_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A36%3A58.147084176+UTC+%2B00%3A00%7D']
    


    3) '='에서 분할하여 각 쿠키를 새로운 배열 배열에 매핑합니다.

    // original array after .split
    [
     'FLIPPER_ID=flipper_on', 
     'info_token=%7B%3Aaccess_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A11%3A58.265440745+UTC+%2B00%3A00%2C+%3Arefresh_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A36%3A58.147084176+UTC+%2B00%3A00%7D'
    ]
    // after we use .map
    [
      ['FLIPPER_ID', 'flipper_on']
      ['info_token', '%7B%3Aaccess_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A11%3A58.265440745+UTC+%2B00%3A00%2C+%3Arefresh_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A36%3A58.147084176+UTC+%2B00%3A00%7D']
    ]
    


    4) 'info_token'과 일치하는 경우 쿠키의 키|값 쌍을 파괴하고 decodedURIComponent 문자열로 해석되는 값으로 다른 함수를 호출하여 사용 가능한 단일 개체로 줄입니다.

    // String before decodeURIComponent is called
    const nonDecoded = '%7B%3Aaccess_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A11%3A58.265440745+UTC+%2B00%3A00%2C+%3Arefresh_token_expiration%3D%3EFri%2C+17+Jun+2022+16%3A36%3A58.147084176+UTC+%2B00%3A00%7D';
    // String after decodedURIComponent is called
    const decoded = '{:access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00,+:refresh_token_expiration=>Fri,+17+Jun+2022+16:36:58.147084176+UTC++00:00}'
    


    쿠키 개체 형식 만들기의 2부OurCookie 함수




    function formatOurCookie(unformattedCookieString) {
      return unformattedCookieString
        // Creates an array by splitting on ',+:' to get the access token and refresh token
        .split(',+:')
        .reduce((obj, cookieVal) => {
          // Destructure the key|value pair of the token's name and its expiration date and uses Regex to remove {: and }
          const [key, val] = cookieVal
            .replace(/{:|}/g, '').split('=>')
          // Update the value by replacing the '+' with spaces and removing the UTC timezone ending
          const formattedValue = val
            .replaceAll('++00:00', '')
            .replaceAll('+', ' ')
          // Return's the accumulator and the key|value pair with a usable JavaScript Date object
          return {
            ...obj,
            [key]: new Date(formattedValue)
          }
      }, {})
    }
    
    


    formatOurCookie 함수 분석 파트 2



    1) unformattedCookieString 문자열이 될 decodeURIComponent 매개변수를 가져오고 ',+:'에서 split 메소드를 사용하여 access_token_expiration 및 refresh_token_expiration을 배열로 가져옵니다.

    // original string
    '{:access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00,+:refresh_token_expiration=>Fri,+17+Jun+2022+16:36:58.147084176+UTC++00:00}'
    // array split on the `',+:'`
    [
     '{:access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00',
     'refresh_token_expiration=>Fri,+17+Jun+2022+16:36:58.147084176+UTC++00:00}'
    ]
    


    2) .reduce 메서드를 사용하여 분할 배열을 반복하여 단일 개체로 줄이는 것을 목표로 합니다.

    3) 다음과 같이 키|값 쌍을 분해하고 싶습니다.

    ㅏ. 먼저 문자열에서 :{}의 모든 인스턴스를 제거합니다.

    // original (removes `:{`)
    '{:access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00'
    // after removes `:{`
    'access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00'
    // after removes `}`
    'refresh_token_expiration=>Fri,+17+Jun+2022+16:36:58.147084176+UTC++00:00'
    


    비. 그런 다음 .split 메서드를 사용하여 =>에서 문자열을 분할합니다.

    // original
    'access_token_expiration=>Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00'
    // transformed
    [
     'access_token_expiration', 
     'Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00'
    ]
    


    씨. +를 단일 공백으로 바꾸고 ++00:00를 제거하여 키 값을 사용 가능한 형식으로 지정합니다.

    // original
    'Fri,+17+Jun+2022+16:11:58.265440745+UTC++00:00'
    // formatted
    'Fri, 17 Jun 2022 16:11:58.265440745 UTC'
    


    4) 누산기를 반환하고 위의 문자열을 사용 가능한 JavaScript 날짜로 강제 변환합니다.

    TL/DR




    const oAuthCookieObject = document.cookie
      .split(';')
      .map(cookie => cookie.split('='))
      .reduce((_, [cookieKey, cookieValue]) => ({
        ...(cookieKey.includes('info_token') && {
          ...formatOAuthCookie(decodeURIComponent(cookieValue))
        })
      }), {});
    
    function formatOurCookie(unformattedCookieString) {
      return unformattedCookieString
        .split(',+:')
        .reduce((obj, cookieVal) => {
          const [key, val] = cookieVal
            .replace(/{:|}/g, '').split('=>')
          const formattedValue = val
            .replaceAll('++00:00', '')
            .replaceAll('+', ' ')
          return {
            ...obj,
            [key]: new Date(formattedValue)
          }
      }, {})
    }
    


    여러분 중 일부가 도움이 되었기를 바랍니다. 건배! 🎉

    좋은 웹페이지 즐겨찾기