json 웹 token 실천 로그 인 및 검사 코드 검증

8924 단어
작년 에 나 는 소개 jwt 의 글 을 한 편 썼 다.
이 글 은 특별한 사용자 로그아웃 및 단일 사용자 다 중 장치 로그 인 수요 가 없 으 면 jwt 를 사용 할 수 있 으 며, jwt 의 가장 큰 특징 은 상태 가 없고 암호 화 되 지 않 는 것 이 라 고 지적 했다.
사용자 로그 인 외 에 도 jwt 인증 메 일 인증 코드 를 사용 할 수 있 습 니 다. 사실 핸드폰 인증 코드 도 검증 할 수 있 습 니 다. 하지만 제 주머니 가 부 끄 러 운 점 을 감안 하여 메 일 을 검증 할 수 밖 에 없습니다.
또한, 나 는 이미 나의 실험 밭 에서 실천 을 했 지만, 현재 전단 코드 는 비교적 초라 하고, 심지 어 는 실패 한 피드백 힌트 도 없다.왜 전단 이 초라 하 게 쓰 여 있 는 지 에 대해 서 는 전단 의 코드 양 이 백 엔 드 에 비해 너무 많 기 때 문 입 니 다.
또한, graphql 에 익숙 하 다 면 이 프로젝트 의 graphql - playground 에서 도 효 과 를 볼 수 있 습 니 다.
본문 주소 shanyue. tech / post / jwt - an...
인증번호 보 내기
검사 하기 전에 메 일과 문자 메 시 지 를 보 낼 수 있 는 무 작위 숫자 에 맞 춰 야 합 니 다.다음 코드 세 션 을 사용 하여 6 자리 숫자의 랜 덤 코드 를 만 들 고 함수 로 포장 할 수 있 습 니 다.
const verifyCode = Array.from(Array(6), () => parseInt((Math.random() * 10))).join('')

전통 적 인 상태 있 는 솔 루 션 을 사용 하려 면 서버 에서 사용자 메 일과 랜 덤 코드 의 키 쌍 을 유지 해 야 하 며, 사용 jwt 도 전단 에 token 을 되 돌려 주 고 인증 코드 를 검사 해 야 합 니 다.
우 리 는 jwt 가 데이터 암호 화 보 다 는 데이터 의 완전 성 만 검증 할 수 있다 는 것 을 안다.이때 사용자 메 일 및 검사 코드 를 짝 짓 기 할 때 payload 에 넣 고 jwt 명문 으로 데 이 터 를 전송 하면 검사 코드 가 유출 된다.
//      ,     
jwt.sign({ email, verifyCode }, config.jwtSecret, { expiresIn: '30m' })

그러면 어떻게 검사 코드 가 누설 되 지 않 고 데 이 터 를 정확하게 검사 할 수 있 습 니까?
우 리 는 시 크 릿 이 누설 되 지 않 는 다 는 것 을 알 고 있 습 니 다. 이때 체크 코드 를 시 크 릿 에 넣 고 짝 짓 기 를 완성 합 니 다.
//            
const token = jwt.sign({ email }, config.jwtSecret + verifyCode, { expiresIn: '30m' })

서버 에서 메 일 을 보 내 는 동시에 token 을 전단 에 다시 전달 하고 등록 할 때 백 엔 드 로 보 내 검증 합 니 다. 이것 은 제 프로젝트 에서 검증 에 관 한 코드 입 니 다 graphql.graphql 을 모 르 시 면 위조 코드 로 도 보 실 수 있 습 니 다. 대충 알 수 있 을 겁 니 다.
type Mutation {
  #     
  #      token,        token,       
  sendEmailVerifyCode (
    email: String! @constraint(format: "email")
  ): String!
}
const Mutation = {
  async sendEmailVerifyCode (root, { email }, { email: emailService }) {
    //        
    const verifyCode = Array.from(Array(6), () => parseInt((Math.random() * 10))).join('')
    // TODO          ,       ,    Mutation     ,        ...
    //      ,     
    emailService.send({
      to: email, 
      subject: '【    】    ——    ',
      html: `         ,         :${verifyCode}(           ,  30       )

`
}) return jwt.sign({ email }, config.jwtSecret + verifyCode, { expiresIn: '30m' }) } }

주제 밖의 말, 메 일 을 보 내 는 데 도 몇 가지 문제 가 있 지만, 여 기 는 우선 그것 을 상관 하지 않 고, 나중에 실현 되면 다시 글 을 써 서 총 결 해 보 자.
  • 만약 에 메 일이 서비스 에 의 해 제공 된다 면 비동기 서비스 와 동기 화 서 비 스 를 어떻게 고려 합 니까
  • 메시지 큐 처리, 메 일 발송 은 신뢰성 을 요구 하지 않 으 며 UDP
  • 와 같 습 니 다.
  • 사용자 가 짧 은 시간 에 대량의 메 일 을 보 내지 않도록 흐름 제한 (RateLimit)
  • 을 어떻게 실현 합 니까?
    문제 밖의 문 제 는 일반적으로 메 일이 나 핸드폰 문자 메 시 지 를 보 내기 전에 사용자 의 진실성 검사 와 흐름 제한 을 위 한 이미지 검사 코드 가 필요 하 다.사진 검사 코드 도 jwt 를 통 해 이 루어 질 수 있다.
    책.
    등록 이 훨씬 간단 합 니 다. 클 라 이언 트 가 들 어 온 데 이 터 를 메 일 로 검사 하고 검사 에 성공 한 후에 바로 입고 하면 됩 니 다. 다음은 graphql 코드 입 니 다.
    type Mutation {
      #   
      createUser (
        name: String!
        password: String!
        email: String! @constraint(format: "email")
        verifyCode: String!
        #            token
        token: String!
      ): User!
    }
    
    const Mutation = {
      async createUser (root, { name, password, email, verifyCode, token }, { models }) {
        const { email: verifyEmail } = jwt.verify(token, config.jwtSecret + verifyCode)
        if (email !== verifyEmail) {
          throw new Error('        ') 
        }
        const user = await models.users.create({
          name,
          email,
          //            
          password: hash(password)
        })
        return user
      }
    }
    

    입 고 된 비밀번호 사용 MD5 과 하나의 인자 salt 를 역 처리 할 수 없 는 세부 사항 이 있 습 니 다.
    function hash (str) {
      return crypto.createHash('md5').update(`${str}-${config.salt}`, 'utf8').digest('hex')
    }
    

    문제 외 에 salt JWTsecret 와 같은 문자열 로 설정 할 수 있 습 니까?
    다시 한 번 말씀 드 리 면 여기 입력 한 정확 한 메 일 박스 의 Error 는 Sentry (경보 시스템) 에 보 내지 말 아야 합 니 다. 일부 Error 의 정 보 는 전단 에 직접 표시 되 고 Error 를 어떻게 규범화 하고 분류 하 는 지 알 수 있 습 니 다.
    검사 코드 는 전통 적 인 방법 으로 jwt 와 비교 된다.
    전통 적 인 방법 을 사용 하면 키 / value 데이터베이스 하나만 있 으 면 핸드폰 번호 / 메 일 박스 와 검사 코드 의 대응 관 계 를 유지 할 수 있 으 며 jwt 에 비해 훨씬 간단 하 다.
    로그 인
    로그 인 jwt 을 위 한 graphql 코드
    type Mutation {
      #   ,     null,     
      createUserToken (
        email: String! @constraint(format: "email")
        password: String!
      ): String
    }
    
    const Mutation = {
      async createUserToken (root, { email, password }, { models }) {
        const user = await models.users.findOne({
          where: {
            email,
            password: hash(password)
          },
          attributes: ['id', 'role'],
          raw: true
        })
        if (!user) {
          //            
          return
        }
        return jwt.sign(user, config.jwtSecret, { expiresIn: '1d' })
      }
    }
    

    공중 호 산월 행 을 주목 하고 나의 기술 성장 을 기록 하 며 교 류 를 환영 합 니 다.
    다음으로 전송:https://juejin.im/post/5cc459976fb9a032212cc73b

    좋은 웹페이지 즐겨찾기