쿠키 및 로그인 등록

14871 단어
우선 간단한 등록 페이지sign_up.html(전단)
    

등록


사용자가 입력한 내용을 해시에 넣기 (앞부분)
        let $form = $('#signUpForm')
        let hash = {}
        $form.on('submit', (e) => {
            e.preventDefault()
            let need = ['email', 'password', 'password_confirmation']
            need.forEach( (name) => {
                let value = $form.find(`[name = ${name}]`).val()
                hash[name] = value
            })
        })  // hash  {email: "xx", password: "xx", password_confirmation: "xx"}

서버 주세요.js에 루트를 추가합니다. 요청 경로가/sign_인 경우up, 현재 디렉터리의sign_ 보이기up.html 파일(백엔드)
 if(path === '/sign_up'){
    let string = fs.readFileSync('./sign_up.html', 'utf8')
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(string)
    response.end()
 }
node server 8080 서버를 열면 http://localhost:8080/sign_up에 방문하면 우리가 쓴 등록 페이지를 볼 수 있습니다.Ajax post 요청: jQuery를 보내 보십시오.post()(프런트엔드)
$.post('/sign_up', hash)
      .then( (response) => {
          console.log(response) // html 
      }, () => {
          console.log(‘error’)
      })

서버 때문에 html 형식의 문자열을 출력합니다.js에 요청 경로가/sign_이면up은 요청이 성공했음을 표시하고 문자열을 되돌려줍니다.
이것은post 요청이기 때문에, 루트에서 요청 방식을 get으로 제한하면,'error'를 출력합니다. (백엔드)
 if(path === '/sign_up' && method === 'GET'){
    let string = fs.readFileSync('./sign_up.html', 'utf8')
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(string)
    response.end()
 }

그래서post의 루트를 요청하는 방법을 추가해야 합니다: (백엔드)
 if(path === '/sign_up' && method === 'POST'){
    readBody(request).then( (body) => {
        response.statusCode = 200
        response.end()
    })    
 } // post /sign_up,  (Form Data), 'email=1&password=2&password_confirmation=3'

// (Form Data) ,Node.js , :
// , Promise 
function readBody(request){
  return new Promise((resolve, reject)=>{
    let body = []
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      body = Buffer.concat(body).toString();
      resolve(body)
    })
  })
}

현재 사용자가 sign_uppost 요청을 보냅니다. 서버에서 받은 요청의 네 번째 부분은 문자열'email=1&password=2&password_confirmation=3'입니다. split () 방법으로 해시로 만듭니다. (백엔드)
let strings = body.split('&') // ['email=1', 'password=2', 'password_confirmation=3']
let hash = {}
strings.forEach((string) => {
    let parts = string.split('=') // ['email', '1']
    let key = parts[0]
    let value = parts[1]
    hash[key] = (value) // hash['email'] = '1'
})

상기에서 한 일을 총괄하면 클라이언트가 폼 내용을 하나의hash에 수집하여 하나의 문자열로 서버에 전달하고 서버는 하나의 문자열 형식으로 폼 내용을 가져와hash로 복원한다.
이것이 바로 전방에서 백엔드로 데이터를 전달하는 방식이다. 전방은 모든 것을 하나의 문자열로 백엔드에 전달하고 백엔드는 문자열에서 필요한 구조에 따라 해석한다.
현재 서버에 폼 정보를 포함하는hash가 있습니다. 계속 검증하십시오. (백그라운드)
let {email, password, password_confirmation} = hash
if(email.indexOf('@') === -1){ // @
    response.statusCode = 400
    response.setHeader('Content-Type', 'application/json;charset=utf-8') //jQuery json JSON.parse()
    response.write(`{
        "errors": {
            "email": "invalid"
        }
    }`)
}else if(password !== password_confirmation){ // 
    response.statusCode = 400
    response.write('password not match')
}else{
    response.statusCode = 200
}

(프런트엔드)
$.post('/sign_up', hash)
                .then( (response) => {
                    console.log(response)
                }, (request) => {
                    let {errors} = request.responseJSON
                    if(errors.email && errors.email === 'invalid'){
                        $form.find('[name = "email"]').siblings('.error')
                            .text(' ')
                    }
                })

프런트엔드도 요청을 시작하기 전에 검증할 수 있습니다. (프런트엔드) jQuery.each()
            $form.find('.error').each( (index, span) => {
                $(span).text('')
            })
            if(hash['email'] === ''){
                $form.find('[name = "email"]').siblings('.error')
                    .text(' ')
                return
            }
            if(hash['password'] === ''){
                $form.find('[name = "password"]').siblings('.error')
                    .text(' ')
                return
            }
            if(hash['password_confirmation'] === ''){
                $form.find('[name = "password_confirmation"]').siblings('.error')
                    .text(' ')
                return
            }
            if(hash['password'] !== hash['password_confirmation']){
                $form.find('[name = "password_confirmation"]').siblings('.error')
                    .text(' ')
                return
            }

현재 저희가 실현하는 기능은 메일박스, 비밀번호, 비밀번호 검증이 필수적입니다. 비밀번호는 인증 비밀번호와 같습니다(전단 검증). 메일박스에는'@'(백엔드 검증)이 있어야 합니다.앞뒤 코드가 JS이기 때문에 백엔드의 검증 전단은 모두 할 수 있다.그러나 프런트엔드는 검사하지 않을 수 있고, 백엔드는 반드시 검사해야 한다.예를 들어 crul 로 요청을 보내면 서버와 직접 교류할 수 있다.따라서 브라우저의 JS에 의존해서는 안 되고 백엔드가 안전해야 합니다.
검증이 성공하면 서버는 얻은 정보를 데이터베이스에 저장해야 한다.현재 디렉터리에서 db/users 파일을 데이터베이스로 만들고 빈 그룹[]으로 초기화합니다.(백엔드)
var users = fs.readFileSync('./db/users', 'utf8')
try{
  users = JSON.parse(users) //  users JSON , 
}catch(exception){
  users = []
}
users.push({email: email, password: password})
var usersString = JSON.stringify(users) // , 
fs.writeFileSync('./db/users', usersString)
response.statusCode = 200

현재 문제가 하나 있습니다. 같은 메일박스는 여러 번 등록할 수 있습니다.서버는 정보를 데이터베이스에 저장하기 전에 메일박스가 등록되었는지 확인할 수 있습니다. (백엔드)
var users = fs.readFileSync('./db/users', 'utf8')
try {
    users = JSON.parse(users) //  users JSON , 
} catch (exception) {
    users = []
}
let inUse = false
for(let i=0; i

이 등록 프로세스가 완료됩니다.이어서 로그인 기능을 하겠습니다.우선 로그인 페이지sign_in.html: (전단)

    

로그인

let $form = $('#signInForm') let hash = {} $form.on('submit', (e) => { e.preventDefault() let need = ['email', 'password'] need.forEach( (name) => { let value = $form.find(`[name = ${name}]`).val() hash[name] = value }) $form.find('.error').each( (index, span) => { $(span).text('') }) if(hash['email'] === ''){ $form.find('[name = "email"]').siblings('.error') .text(' ') return } if(hash['password'] === ''){ $form.find('[name = "password"]').siblings('.error') .text(' ') return } $.post('/sign_in', hash) .then( (response) => { console.log(response) }, (request) => { let {errors} = request.responseJSON if(errors.email && errors.email === 'invalid'){ $form.find('[name = "email"]').siblings('.error') .text(' ') } }) })

서버에서 sign_in.html 루트 쓰기: (백엔드)
    else if (path === '/sign_in' && method === 'GET') {
        let string = fs.readFileSync('./sign_in.html', 'utf8')
        response.statusCode = 200
        response.setHeader('Content-Type', 'text/html;charset=utf-8')
        response.write(string)
        response.end()
    } else if (path === '/sign_in' && method === 'POST') {
        readBody(request).then((body) => {
            let strings = body.split('&') // ['email=1', 'password=2']
            let hash = {}
            strings.forEach((string) => {
                let parts = string.split('=') // ['email', '1']
                let key = parts[0]
                let value = parts[1]
                hash[key] = decodeURIComponent(value) // hash['email'] = '1'
            })
            
            response.end()
        })
    } 

로그인 페이지는 등록 페이지와 비슷하고 클라이언트는 폼 정보를 해시에 수집하여 요청을 할 때 백엔드에 문자열을 전송한다.백엔드에서 얻은 문자열을 해시로 해석합니다.
백엔드에서 이메일과password를 포함하는 해시를 받은 후 데이터베이스와 비교(데이터베이스에 같은 이메일과password가 있는지 보기), 인증 사용자: (백엔드)
            let { email, password } = hash
            var users = fs.readFileSync('./db/users', 'utf8')
            try {
                users = JSON.parse(users) // []
            } catch (exception) {
                users = []
            }
            let found
            for (let i = 0; i < users.length; i++) {
                if (users[i].email === email && users[i].password === password) {
                    found = true
                    break
                }
            }
            if (found) {
                response.statusCode = 200
            } else {
                response.statusCode = 401
            }

로그인 성공 시 첫 페이지로 이동: (앞면)
$.post('/sign_in', hash)
                .then( (response) => {
                    window.location.href = '/'
                }, (request) => {
                    alert(' ')
                })

현재 문제가 하나 있습니다. 로그인하지 않아도 사용자가 첫 페이지에 직접 접근할 수 있습니다. 로그인한 후에 본 페이지와 같습니다.여기 쿠키가 필요해요.HTTP Set-Cookie 서버는 인증된 사용자가 성공하면 되돌아오는 응답 헤더에 추가합니다Set-Cookie:(백엔드)
if (found) {
    response.setHeader('Set-Cookie', `sign_in_email=${email}`)
    response.statusCode = 200 
} 

개발자 도구의 Preserve log를 선택하고 다시 로그인합니다.우리가 볼 수 있는 것은sign_요청을 시작할 때 받은 응답 헤더 중 하나Set-Cookie: [email protected]가 있습니다. 요청이 성공하면 홈페이지에 요청한 요청 헤더에 이 쿠키를 가지고 있습니다. Cookie: [email protected].
이것이 바로 쿠키의 역할이다. 서버 응답에서 페이지에 쿠키를 보내고 동원된 요청은 모두 이 쿠키를 식별한다.이해: 공원에 처음 들어왔을 때 매표원이 이틀 동안 표(Set-Cookie)를 줬어요. 표가 바로 쿠키예요. 이틀 동안 공원에 여러 번 들어갈 수 있어요. 매번 표를 가지고 매표원에게 보여줘야 해요.
쿠키 특징:
  • 서버 통과Set-Cookie 응답 헤더 설정 쿠키
  • 브라우저가 쿠키를 받은 후 요청할 때마다 쿠키를 가져옵니다
  • 서버가 쿠키를 읽으면 로그인 사용자의 정보를 알 수 있음
  • 질문:
  • 크롬에서 쿠키를 받았는데 사파리로 방문하면 사파리가 쿠키를 가져갈까요?no
  • 쿠키는 어디에 있습니까?Windows는 C디스크의 한 파일에 존재하고 다른 시스템도 하드디스크의 한 파일에 존재한다.
  • 쿠키가 가짜를 만들 수 있습니까?네.Chrome 개발자 도구 Application-Cookies에서 변경할 수 있습니다.그래서 쿠키는 안전하지 않아요.HttpOnly 제한할 수 있습니다.
  • 쿠키에 유효기간이 있습니까? 기본 유효기간은 20분 정도입니다. 브라우저에 의해 결정됩니다.백엔드에서 유효기간을 강제로 설정할 수 있습니다.

  • 이제 로그인한 사용자가 첫 페이지로 이동할 때 자신의 비밀번호를 볼 수 있도록 합니다. (백그라운드)
    if (path === '/') {
            let string = fs.readFileSync('./index.html', 'utf8')
            
            // cookies email
            let cookies = request.headers.cookie.split('; ')   // ['email=1@', 'a=1', 'b=2']
            let hash = {}
            for (let i = 0; i < cookies.length; i++) {
                let parts = cookies[i].split('=')
                let key = parts[0]
                let value = parts[1]
                hash[key] = value
            }
            let email = hash.sign_in_email
           
            // , cookie email 
            let users = fs.readFileSync('./db/users', 'utf8')
            users = JSON.parse(users)
            let foundUser
            for (let i = 0; i < users.length; i++) {
                if (users[i].email === email) {
                    foundUser = users[i]
                    break
                }
            }
            
            // , 
            if (foundUser) {
                string = string.replace('__password__', foundUser.password)
            } else {
                string = string.replace('__password__', ' ')
            }
            response.statusCode = 200
            response.setHeader('Content-Type', 'text/html;charset=utf-8')
            response.write(string)
            response.end()
        }
    

    index.html:
    
        

    당신의 비밀번호는:'__password__'


    프로세스 요약:
  • 사용자 열기sign_up 등록, 서버에post 요청, 이메일,password,password_ 보내기confirmation;
  • 서버 검증을 통해 사용자 정보를 데이터베이스에 기록하고 등록에 성공했다고 알려준다.
  • 사용자 열기sign_in 로그인,post 요청 보내기,이메일과password 보내기;
  • 서버 인증 통과, Set-Cookie;
  • 사용자가 쿠키를 가지고 첫 페이지를 열고 get 요청을 발송한다.
  • 서버는 쿠키를 읽고 쿠키에서 이메일을 얻으며 이메일에 따라 데이터베이스에서 일치하는 사용자 정보를 찾아 페이지에 쓴다.
  • 이렇게 로그인한 사용자가 첫 페이지에 들어갈 때 자신의 정보를 볼 수 있다.
  • 로그인하지 않은 방문객이 첫 페이지에 들어가 다른 페이지를 본다.

  • 끝나다
    전체 코드

    좋은 웹페이지 즐겨찾기