본문 바로가기

C#

.net - 회원가입&로그인 (5)

회원가입 -> 사용자가 정보 입력 -> DB 저장

로그인 -> 사용자 정보 입력 -> 사용자 정보 보유

*Java : Spring Security(보안) 검색 -> Spring프레임워크를 이용한 로그인 기능 예제 

*C# : Identity Security(보안) 

- 사용자 인증 (로그인)

- 사용자 룰 (개발자, 일반유저, VIP)

- SMS 인증 -> 휴대폰, 이메일 인증 (유료)

- 구글 이메일 인증(무료)

 

Session을 이용한 로그인, 회원가입 구현

로그인 2가지 방법론

1. Sesssion : 웹 서버가 사용자 정보를 로그아웃이나 브라우저를 끌때까지 메모리에 담고 있음

장점 : 보안이 높다 (웹서버가 해킹이 되지 않는 이상 보안됨)

단점 : 웹 서버 메모리 부하가 높아진다. (네이버같이 유저가 많은 곳은 메모리 부하가 됨)

 

2. Cookie : 사용자 정보를  브라우저에 전달하여 사용자 PC에 쿠키파일로 저장

장점 : 웹 서버 부하 낮아진다.

단점 : 보안성 낮아진다.

 

결론 : 쿠키방식을 제일 많이 쓴다.

쿠키 암호화 / 복호화(암호화된거 품) : 쿠키 암호화한걸 서버에서 복호화해서 로그인 정보를 확인

-> 위변조의 위험이 있다. ex) 실제 로그인을 한것처럼 변조

SSL 인증서 : 인증, 입출력에 관한 내용들을 SSL인증화한다. (유료(업체 : 매년결제)), 무료(open SSL))

               : SSL 인증서로부터 쿠키를 검사하여 위변조 여부를 검사하고 사용자 인증 절차를 밟는다.

 

<get/post>

get : DB -> 받는다

post : DB <- 전달

 

<크롬 캐쉬>

css, 자바스크립트를 캐쉬화하여 저장하므로 변경해도 캐쉬가 저장되어 있어 변경값이 안보인다.

따라서 css, 자스를 변경했을 경우 캐쉬를 삭제해야한다.

 

<디버깅>

F9 : 디버깅 포인트 찍기

F11 : 한줄씩 넘어간다.

F5 : 한번에 다 넘어가버린다.

shift + F5 : 디버깅 취소

 

<CPU보기>

밑 -> 작업관리자 -> 성능탭

 

<asp .net Core 2가지 트랙>

1. LTS (Long Term Support) : 느리게 업그레이드

2. Current : 빠르게 업그레이드

 

<sln 확장자> - 솔류션 확장자

 

<비주얼스튜디오 버전 업데이트>

1. Properties - 대상 프레임워크 - 버전에 맞게 설정

2. 종속성 - 누겟패키지 업데이트 할 것들 업데이트 시켜주기

3. 솔루션 빌드 하기

4. 실행시켜서 정상적으로 실행되는지 확인하기

 

<ViewModel(뷰모델)> : 뷰를 위한 모델(연결해주기 위해 만듬)

 

<MVVM> M(모델).V(뷰모델).VM(뷰모델)

 

<설치>

누겟에 session 검색 

Microsoft.AspnetCore.Session 다운

 

<-------정리------->

 

<View>

class="form-horizontal" : 부트스트랩 form 표현방식

 

* form submit 보내는 위치 지정

1. form태그에 속성 넣기

- asp-controller="User" : User라는 컨트롤러

- asp-action="login" : login 메소드

 

2. 모델 선언

@model 솔류션이름.모델폴더이름.모델이름

 

3. 모델변수명 = 입력값

-  asp-for="모델변수명"

 

4. 필수 입력값에 경고문

<span class="text-danger" asp-validation-for="userID"></span>

 

Join.cshtml (View)

@model MyHomePage.Models.NewFolder.User

<h1>회원가입</h1>
<form class="form-horizontal" method="post" asp-controller="User" asp-action="join">
    <div class="form-group">
        <input type="text" class="form-control" asp-for="name" placeholder="이름" />
        <span class="text-danger" asp-validation-for="name"></span>
    </div>

    <div class="form-group">
        <input type="number" class="form-control" asp-for="age" placeholder="나이" />
    </div>

    <div class="form-group">
        <input type="radio" class="radio-inline" asp-for="gender" value="1"/>남자
        <input type="radio" class="radio-inline" asp-for="gender" value="2"/>여자
    </div>

    <div class="form-group">
        <input type="text" class="form-control" asp-for="userID" placeholder="ID" />
        <span class="text-danger" asp-validation-for="userID"></span>
    </div>

    <div class="form-group">
        <input type="password" class="form-control" asp-for="userPW" placeholder="PW" /><br />
        <span class="text-danger" asp-validation-for="userPW"></span>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-primary">회원가입</button>
        <button type="reset" class="btn btn-warning" href="../Home/Index.cshtml">취소</button>
    </div>
    
</form>

Login.cshtml (View)

@model MyHomePage.ModelView.Login
<h1>로그인</h1>

<form class="form-horizontal" method="post" asp-controller="User" asp-action="login">
    <div class="form-group">
        <input type="text" class="" asp-for="userID" placeholder="ID" />
        <span class="text-danger" asp-validation-for="userID"></span>
    </div>

    <div class="form-group">
        <input type="password" class="" asp-for="userPW" placeholder="PW" />
        <span class="text-danger" asp-validation-for="userPW"></span>
    </div>

    <div class="form-group">
        <button type="submit" class="btn btn-success">로그인</button>
        <button type="reset" class="btn btn-warning">취소</button>
    </div>
</form>

 

<Model>

* not null 타입에 null값일때 에러메시지(View - <span> - asp-validation-for="변수명")

[Required(ErrorMessage ="이름을 입력해주세요")]

User.cs (클래스)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace MyHomePage.Models.NewFolder
{
    public class User
    {
        [Required(ErrorMessage ="이름을 입력해주세요")]
        public string name { get; set; }

        public int age { get; set; }

        public int gender { get; set; }

        [Key]
        public string userID { get; set; }

        [Required(ErrorMessage ="비밀번호를 입력하세요")]
        public string userPW { get; set; }
    }
}

<ModelView : Login하기 위해 만들어진 모델>

Login.cs (클래스)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace MyHomePage.ModelView
{
    public class Login
    {
        [Required(ErrorMessage = "아이디를 입력하세요")]
        public string userID { get; set; }

        [Required(ErrorMessage = "비밀번호를 입력하세요")]
        public string userPW { get; set; }
    }
}

 

<Controller>

1. if (ModelState.IsValid) : not null 타입에 필수 값 있는지 확인 (있으면 true, 없으면 false)

2. using함수 : DB커넥션 열리고 끝날때 닫힘

3. RedirectToAction("이동할 View페이지", "컨트롤러이름")

 

* 세션

 - HttpContext.Session.SetInt32(key:식별자, value:데이터값);

 

AccountController.cs (MVC컨트롤러 클래스)

using Join.DataContext;
using Join.Models;
using Join.ViewModel;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Linq;

namespace Join.Controllers
{
    public class AccountController : Controller
    {
        /// <summary>
        /// 로그인
        /// </summary>
        /// <returns></returns>
        public ActionResult Login()
        {
            return View();
        }
        /// <summary>
        /// 로그인할때 동작하는 메소드
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Login(LoginViewModel model)
        {
            if (ModelState.IsValid)
            {
                using (var db = new joinNoteDBContext())
                {
                    //Linq(링크쿼리) - 메서드 체이닝(메서드.메서드)
                    //FirstOrDefault : DB에 제일 첫번째 행이 출력된다.
                    // A=>B(람다식) : A에서 B로 간다
                    //var user = db.생성한 db 커넥션.FirstOrDefault.......
                    //var user = db.users.              model.userID를 새로운 스트링 객체로 선언해 비교함으로 메모리 누수 발생
                    //    FirstOrDefault(u=>u.UserID == model.UserID && u.UserPW == model.UserPW); 
                    var user = db.users.
                        FirstOrDefault(u => u.UserID.Equals(model.UserID) && u.UserPW.Equals(model.UserPW));
                    if(user != null)
                    {
                        //세션 추가
                        //HttpContext.Session.SetInt32(key:식별자, value:데이터값);
                        HttpContext.Session.SetInt32("User_Loing_Key", user.UserNO);
                        //로그인 성공
                        return RedirectToAction("LoginOK", "Home");
                    }
                }
                //로그인 실패 string.Empty == ""
                ModelState.AddModelError(string.Empty, "사용자 ID 혹은 PW가 올바르지 않습니다.");
            }
            return View(model);
        }

        public ActionResult Logout()
        {
            //세션 삭제
            HttpContext.Session.Remove("User_Loing_Key");
            //HttpContext.Session.Clear(); -> 모든 세션 삭제 ex) 많은 사람이 로그인하면 다 삭제됨.
            //따라서 메모리가 가득찼을때 관리자들이 사용하는 코드이다.
            return RedirectToAction("Index","Home");
        }

        /// <summary>
        /// 회원 가입 페이지 이동
        /// </summary>
        /// <returns></returns>
        public ActionResult Join()
        {
            return View();
        }

        /// <summary>
        /// 회원가입 post 정보 전달을 받는다.
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Join(User model)
        {
            //사용자에게 필수 입력을 받아야하는 값들을 입력받았는지 확인.ex)View- id,pw,name//model-[Required]
            //입력값이 모두 있으면 true /하나라도 없으면 false
            if (ModelState.IsValid)
            {
                //자바에서 DB입출력 시 받을때 커넥션을 open, 끝나면 close로 자원을 쓰고 나면 반환을 해야 
                //메모리 누수가 없기때문에 반드시 해줘야하는데 C#에서는 using문으로 해결한다.
                //Java try(SqlSession){} cahth(){}
                //C#
                //using문으로 데이터 커넥션을 열고 using문이 끝나면 자동으로 닫는다.
                using (var db = new joinNoteDBContext())
                {
                    db.users.Add(model);//메모리에 올림
                    db.SaveChanges();//실제 DB로 저장
                }
                return RedirectToAction("Index", "Home");//home컨트롤러에 있는 index뷰로 이동한다.
            }
            return View(model);
        }
    }
}

 

 

<Shared : 메뉴 탭>

* 세션

 - Context.Session.GetInt32("User_Loing_Key")

 

_Layout.cshtml

@using Microsoft.AspNetCore.Http

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Join</title>

    <environment include="Development">
        <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment exclude="Development">
        KR
        asp.net




        9+

        아바타 이미지



        18/35
        [ASP.NET MVC] 8. 회원가입 기능 만들기
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>
</head>
<body>
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">Join</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
                </ul>
                <ul class="nav navbar-nav navber-right">
                    @if (Context.Session.GetInt32("User_Loing_Key") == null)
                    {
                        <li><a asp-area="" asp-controller="Account" asp-action="Login">로그인</a></li>
                        <li><a asp-area="" asp-controller="Account" asp-action="Join">회원가입</a></li>
                    }
                    else
                    {
                        <li><a asp-area="" asp-controller="Account" asp-action="Logout">로그아웃</a></li>
                    }

                </ul>
            </div>
        </div>
    </nav>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()
        <hr />
        <footer>
            <p>&copy; 2020 - Join</p>
        </footer>
    </div>

    <environment include="Development">
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    <environment exclude="Development">
        <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"
                asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
                asp-fallback-test="window.jQuery"
                crossorigin="anonymous"
                integrity="sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT">
        </script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"
                asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
                asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
                crossorigin="anonymous"
                integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd">
        </script>
        <script src="~/js/site.min.js" asp-append-version="true"></script>
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

'C#' 카테고리의 다른 글

asp.net7 - 게시판(+Trumbowyg 라이브러리 추가)  (0) 2020.08.11
asp.net 6 - 게시판, 세션  (0) 2020.08.09
.net 강의3 - MSSQL DB연동  (0) 2020.07.28
asp.net4 - 데이터베이스 생성하기  (0) 2020.07.28
.net 강좌2  (0) 2020.07.26