MVC 4에서 OAuth 공급자 이용하기

등록일시: 2013-03-11 11:13,  수정일시: 2013-11-29 22:58
조회수: 4,659
이 문서는 ASP.NET MVC 기술을 널리 알리고자 하는 개인적인 취지로 제공되는 번역문서입니다. 이 문서에 대한 모든 저작권은 마이크로소프트에 있으며 요청이 있을 경우 언제라도 게시가 중단될 수 있습니다. 번역 내용에 오역이 존재할 수 있고 주석은 번역자 개인의 의견일 뿐이며 마이크로소프트는 이에 관한 어떠한 보장도 하지 않습니다. 번역이 완료된 이후에도 대상 제품 및 기술이 개선되거나 변경됨에 따라 원문의 내용도 변경되거나 보완되었을 수 있으므로 주의하시기 바랍니다.

본 자습서에서는 페이스북, 트위터, 마이크로소프트, 구글 등과 같은 외부 공급자의 신원증명을 이용해서 로그인 할 수 있는 ASP.NET MVC 4 웹 응용 프로그램을 구축해보고, 이러한 공급자들이 제공해주는 몇 가지 기능들을 여러분의 웹 응용 프로그램에 통합하는 방법을 살펴봅니다. 다만, 본 자습서에서는 간단한 설명을 위해서 페이스북 신원계정을 이용한 작업에 대해서만 살펴볼 것입니다.

여러분의 웹 사이트에서 이런 신원계정들을 활성화시키면 다양한 이점들을 얻을 수가 있는데, 가장 중요한 점은 수 백 만명의 사용자들이 이런 공급자들의 계정을 이미 보유하고 있다는 사실입니다. 그리고, 그런 사용자들은 대체적으로 새로운 신원증명을 생성하거나 일일이 기억해야 할 필요가 없는 경우, 여러분의 사이트에 거부감 없이 로그인 할 가능성이 더 높습니다. 또한, 사용자들이 이런 공급자들 중 하나를 이용해서 로그인을 하고 난 뒤에는, 해당 공급자의 소셜 관련 기능들을 여러분의 사이트에 통합할 수도 있습니다.

작업목표

본 자습서는 다음과 같은 두 가지 핵심 목표를 갖고 있습니다:

  1. OAuth 공급자 신원증명을 이용한 사용자 로그인을 활성화시킵니다.
  2. 공급자의 계정 정보를 조회하고, 그 정보를 여러분의 사이트에 등록된 계정 정보와 통합합니다.

본 자습서의 예제는 페이스북을 인증 공급자로 이용하도록 작성되었습니다. 그러나, 예제 코드를 수정해서 다른 공급자를 이용하도록 변경할 수도 있습니다. 대부분의 공급자 활성화를 구현하는 과정들은 본 자습서에서 여러분이 살펴보게 될 그것과 매우 비슷합니다. 공급자의 API를 직접 호출하는 부분들만 특별히 유의해서 살펴보면 됩니다.

준비사항

또는

본 자습서는 여러분이 ASP.NET MVC와 Visual Studio에 대한 기본적인 지식을 이미 습득하고 있다고 가정합니다. 만약, ASP.NET MVC 4에 대한 기본적인 정보가 필요하다면, Intro to ASP.NET MVC 4를 참고하시기 바랍니다.

프로젝트 생성하기

비주얼 스튜디오에서 "OAuthMVC"라는 이름으로 새로운 ASP.NET MVC 4 웹 응용 프로그램을 생성합니다. 타겟은 .NET 프레임워크 4.5 또는 4로 지정하면 됩니다.

create project

새 ASP.NET MVC 4 프로젝트 창에서 인터넷 응용 프로그램을 선택하고 뷰 엔진으로는 최초에 선택되어 있는 Razor를 그대로 놔둡니다.

select Internet Application

공급자 활성화시키기

인터넷 응용 프로그램 템플릿을 이용해서 MVC 4 웹 응용 프로그램을 생성하면 App_Start 폴더에 AuthConfig.cs라는 이름의 파일이 자동으로 만들어집니다.

AuthConfig file

이 AuthConfig.cs 파일에는 외부 인증 공급자에 대한 클라이언트 등록 코드가 이미 작성되어 있습니다. 다만, 이 코드들은 기본적으로 주석 처리가 되어 있기 때문에, 어떠한 외부 공급자도 활성화되어 있지 않은 상태입니다.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        // 이 사이트의 사용자가 다른 사이트(예: Microsoft, Facebook 및 Twitter)의 계정을 사용하여
        // 로그인할 수 있도록 하려면 이 사이트를 업데이트해야 합니다.
        // 자세한 내용은 http://go.microsoft.com/fwlink/?LinkID=252166을 참조하십시오.
 
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");
 
        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");
 
        //OAuthWebSecurity.RegisterFacebookClient(
        //    appId: "",
        //    appSecret: "");
 
        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

따라서, 먼저 사용하고자 하는 외부 인증 클라이언트의 코드 주석을 풀어야만 합니다. 여러분이 사이트에 포함시키고자 하는 공급자의 주석만 풀면 됩니다. 본 자습서에서는 페이스북 신원계정만 활성화시킬 것입니다.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");
 
        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");
 
        OAuthWebSecurity.RegisterFacebookClient(
            appId: "",
            appSecret: "");
 
        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

이 코드를 자세히 살펴보면 주석을 푼 메서드에 매개변수로 빈 문자열들이 지정되어 있다는 것을 알 수 있습니다. 이 매개변수에는 빈 문자열이 허용되지 않기 때문에, 지금 현재 상태에서 응용 프로그램을 실행시키면 인자와 관련된 예외가 발생하게 됩니다. 매개변수에 적절한 값을 지정하기 위해서는 먼저 다음 절에서 살펴보게 될 과정을 통해서 여러분의 웹 사이트를 외부 공급자에 등록해야만 합니다.

외부 공급자 등록하기

외부 공급자의 신원계정을 이용해서 사용자를 인증하려면 먼저 여러분의 웹 사이트를 해당 공급자에 등록해야만 합니다. 그 과정 중에 몇 가지 정보들을 (Key나 Id, 또는 Secret 등) 부여 받게 되는데, 클라이언트를 등록할 때 바로 이 정보들을 설정해야 합니다. 그리고, 이용하고자 하는 공급자의 계정도 보유하고 있어야만 합니다.

본 자습서에서는 웹 사이트를 공급자에 등록하기 위해서 수행해야 하는 모든 과정들을 보여주고 있지는 않습니다만, 그 과정은 대부분 어렵지 않습니다. 웹 사이트를 등록하려면 각 사이트들이 제공하는 지시 사항들을 그대로 따르기만 하면 됩니다. 다음의 개발자 사이트를 통해서 여러분의 웹 사이트를 등록할 수 있습니다:

다음 이미지에서 볼 수 있는 것처럼 페이스북에 사이트를 등록하는 경우에는, 도메인 항목에 "localhost"를 지정하거나 URL 항목에 "http://localhost/"를 지정할 수 있어서 편리합니다. 대부분의 공급자에서는 이렇게 localhost를 사용할 수 있지만 마이크로소프트 공급자를 사용하는 경우에는 사용할 수 없습니다. 마이크로소프트 공급자에서는 유효한 실제 웹 사이트 URL을 지정해야만 합니다.

register site

이 이미지에서 App Id 와 App Secret, 그리고 연락처 메일의 정보값은 의도적으로 지운 상태이므로 참고하시기 바랍니다. 여러분이 실제로 사이트를 등록할 때는 이 값들이 정상적으로 제공될 것입니다. App Id 와 App Secret 값들은 응용 프로그램에 추가해야 하기 때문에 메모해놔야 합니다.

테스트 사용자 생성하기

만약 여러분이 기존에 사용하던 페이스북 계정을 본문의 테스트에 사용해도 무관하다면 이 절은 무시해도 무관합니다.

페이스북 앱 관리 페이지를 이용하면 응용 프로그램에 사용할 테스트 사용자를 손쉽게 생성할 수 있습니다. 이 테스트 계정을 이용해서 여러분의 사이트에 로그인 해 볼 것입니다. 좌측 네비게이션 패인에서 Roles 링크를 클릭한 다음, Create 링크를 클릭해서 테스트 사용자를 생성합니다.

create test users

그러면, 페이스북 사이트가 자동으로 여러분이 요청한 만큼 테스트 계정을 생성해줄 것입니다.

공급자로부터 받은 응용 프로그램 Id 및 Secret 추가하기

이제 페이스북에서 Id와 Secret을 부여 받았으므로 다시 AuthConfig.cs 파일로 돌아가서 매개변수에 이 값들을 지정할 수 있습니다. 참고로 다음 코드에 지정된 값들은 실제 값은 아닙니다.

public static class AuthConfig
{
    public static void RegisterAuth()
    {
        //OAuthWebSecurity.RegisterMicrosoftClient(
        //    clientId: "",
        //    clientSecret: "");
 
        //OAuthWebSecurity.RegisterTwitterClient(
        //    consumerKey: "",
        //    consumerSecret: "");
 
        OAuthWebSecurity.RegisterFacebookClient(
            appId: "111111111111111",
            appSecret: "a1a1aa111111111a111a111aaa111111");
 
        //OAuthWebSecurity.RegisterGoogleClient();
    }
}

외부 신원계정으로 로그인하기

지금까지 살펴본 내용들이 여러분의 사이트에서 외부 신원계정을 활성화시키기 위해서 수행해야만 하는 작업의 전부입니다. 이제 응용 프로그램을 실행시키고 우측 상단의 로그인(login) 링크를 클릭해봅니다. 그러면, 여러분이 페이스북을 공급자로 등록했다는 것을 템플릿이 자동으로 인식해서 화면에 이 공급자에 대한 버튼을 추가해 준 것을 확인할 수 있을 것입니다. 만약, 여러분이 여러 가지 공급자들을 등록했다면 각각 그에 해당하는 버튼들이 자동으로 추가될 것입니다.

external login

본 자습서에서는 외부 공급자용 로그인 버튼들을 사용자 정의하는 방법은 다루지 않습니다. 그에 대한 보다 자세한 정보는 Customizing the login UI when using OAuth/OpenID를 참고하시기 바랍니다.

이제, Facebook 버튼을 클릭하면 페이스북 신원계정으로 로그인 할 수 있습니다. 이처럼 외부 공급자들 중 한 가지를 선택하면, 먼저 해당 사이트로 전송된 다음, 해당 사이트에서 제공하는 로그인 프롬프트가 나타나게 됩니다.

다음 이미지는 페이스북의 로그인 화면을 보여주고 있습니다. 이 화면을 주의 깊게 살펴보면 여러분이 페이스북 계정을 사용해서 oauthmvcexample이라는 이름의 사이트에 로그인하려 하고 있다는 것을 알려주고 있다는 사실을 확인할 수 있습니다.

facebook authentication

페이스북 신원계정을 이용해서 로그인을 하고 나면, 다음 페이지에서 이 사이트가 기본 정보에 접근할 수 있다는 것을 사용자에게 알려줍니다.

request permission

이제 사용자는 앱으로 가기(Go to App)을 선택한 뒤에 여러분의 웹 사이트에 등록하게 됩니다. 다음 이미지는 페이스북 신원계정으로 로그인한 사용자를 대상으로 한 등록 페이지를 보여주고 있습니다. 대부분 사용자 이름은 공급자에서 가져온 이름으로 미리 입력되어 있을 것입니다.

register

등록(Register) 버튼을 클릭하면 등록이 완료됩니다. 이제 브라우저를 닫도록 합니다.

데이터베이스를 살펴보면 새로운 계정이 추가된 것을 확인할 수 있습니다. 서버 탐색기에서 DefaultConnection 데이터베이스를 연 다음, 테이블(Tables) 폴더를 펼칩니다.

database tables

UserProfile 테이블을 마우스 오른쪽 버튼으로 클릭한 다음, 테이블 데이터 표시(Show Table Data)를 선택합니다.

show data

그러면, 새로 추가된 계정을 확인할 수 있을 것입니다. 그러면 이번에는 webpages_OAuthMembership 테이블을 살펴보시기 바랍니다. 이 테이블에서는 여러분이 방금 추가한 계정의 외부 공급자와 관련된 조금 더 많은 정보들을 확인할 수 있습니다.

만약, 여러분이 외부 공급자를 활성화시키는 것만으로 만족한다면 이로서 모든 작업이 끝난 셈입니다. 그러나, 이어지는 절들에서 살펴볼 것처럼 새로운 사용자를 등록하는 과정 중 공급자로부터 제공되는 정보들을 보다 긴밀하게 통합시킬 수도 있습니다.

사용자 추가 정보를 위한 모델 생성하기

지금까지 내장 계정 등록을 수행하기 위해서는 어떤 추가적인 정보도 가져올 필요가 없습니다. 그러나, 대다수의 외부 공급자들은 사용자에 대해 추가적인 정보들도 제공해줍니다. 이어지는 절들에서는 이런 정보들을 가져와서 데이터베이스에 저장하는 방법에 대해서 살펴보겠습니다. 특히, 그 중에서도 사용자의 전체 이름, 웹 페이지 URI, 그리고 계정이 페이스북에 의해 검증되었는지 여부 등에 대한 값을 가져오는 방법에 관해서 살펴보려고 합니다.

본 자습서에서는 테이블을 추가하고 사용자 추가 정보를 저장하기 위해서 Code First Migrations 기법을 사용할 것입니다. 기존 데이터베이스에 테이블 추가를 해야 하기 때문에, 먼저 현재 데이터베이스의 스냅샷을 생성할 필요가 있습니다. 데이터베이스의 스냅샷을 생성해 놓으면 뒤에 새로운 테이블만 포함된 마이그레이션을 생성할 수 있습니다. 데이터베이스의 현재 스냅샷을 생성하려면:

  1. 패키지 관리자 콘솔(Package Manager Console)을 엽니다.
  2. enable-migrations 명령을 실행합니다.
  3. add-migration initial –IgnoreChanges 명령을 실행합니다.
  4. update-database 명령을 실행합니다.

이제 새로운 속성들을 추가해보겠습니다. Models 폴더에 위치한 AccountModels.cs 파일을 열고, RegisterExternalLoginModel 클래스를 찾습니다. RegisterExternalLoginModel 클래스는 인증 공급자로부터 제공된 값들을 담는 클래스입니다. 다음에 강조된 것과 같이 FullName 및 Link라는 이름의 속성들을 추가합니다.

public class RegisterExternalLoginModel
{
    [Required]
    [Display(Name = "사용자 이름")]
    public string UserName { get; set; }
 
    public string ExternalLoginData { get; set; }
 
    [Display(Name = "전체 이름")]
    public string FullName { get; set; }
 
    [Display(Name = "개인 페이지 링크")]
    public string Link { get; set; }
}

그리고, AccountModels.cs 파일에 ExtraUserInformation라는 이름의 새로운 클래스를 추가합니다. 이 클래스는 데이터베이스에 생성될 새로운 테이블을 나타냅니다.

[Table("ExtraUserInformation")]
public class ExternalUserInformation
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public string FullName { get; set; }
    public string Link { get; set; }
    public bool? Verified { get; set; }
}

마지막으로 UsersContext 클래스에 새로운 클래스를 위한 DbSet 속성을 생성하기 위해서 다음에 강조된 코드를 추가합니다.

public class UsersContext : DbContext
{
    public UsersContext()
        : base("DefaultConnection")
    {
    }
 
    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<ExternalUserInformation> ExternalUsers { get; set; }
}

이제 새로운 테이블을 생성할 준비를 다 마쳤습니다. 다시 패키지 관리자 콘솔을 열고 이번에는:

  1. add-migration AddExtraUserInformation 명령을 실행합니다.
  2. update-database 명령을 실행합니다.

그러면, 새로운 테이블이 기존 데이터베이스에 추가됩니다.

추가 데이터 가져오기

사용자의 추가 데이터를 가져올 수 있는 방법은 모두 두 가지입니다. 그 중, 첫 번째 방법은 인증 요청시 기본적으로 반환되는 사용자 데이터를 저장하는 방법입니다. 그리고, 두 번째 방법은 명시적으로 공급자의 API를 호출해서 보다 다양한 정보를 요청하는 방법입니다. 전체 이름과 링크는 페이스북이 자동으로 그 값을 반환해줍니다. 반면, 페이스북 계정 검증 여부 값은 페이스북 API를 명시적으로 호출해서 얻을 수 있습니다. 이번 절에서는, 먼저 전체 이름과 링크 값을 수집하는 방법을 살펴본 다음, 이어서 검증 값을 조회해보도록 하겠습니다.

사용자 추가 정보를 얻기 위해서 Controllers 폴더에 위치한 AccountController.cs 파일을 엽니다.

이 파일에는 로그인, 등록, 계정관리 등의 로직이 구현되어 있습니다. 그 중에서 ExternalLoginCallback 메서드와 ExternalLoginConfirmation 메서드에 주목해보도록 하겠습니다. 이 메서드들 내부에 코드를 추가하여 응용 프로그램의 외부 로그인 작업을 사용자 정의 할 수 있습니다. ExternalLoginCallback 메서드의 첫 번째 줄은 다음과 같습니다:

AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
    Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));

사용자 추가 데이터는 VerifyAuthentication 메서드의 결과로 반환되는 AuthenticationResult 개체의 ExtraData 속성에 담겨 반환됩니다. 가령, 페이스북 클라이언트는 다음과 같은 값들을 ExtraData 속성에 담아줍니다:

  • id
  • name
  • link
  • gender
  • accesstoken

다른 공급자들도 약간 씩 차이가 나기는 하지만, 이와 거의 비슷한 정보들을 제공해줍니다.

로그인 하는 사용자가 신규 웹 사이트 사용자인 경우, 일부 추가 정보를 조회해서 이를 확인 뷰에 전달해보겠습니다. 메서드 코드의 마지막 부분은 사용자가 사이트의 신규 사용자인 경우에만 실행됩니다. 다음과 같은 코드를:

return View("ExternalLoginConfirmation", new RegisterExternalLoginModel
{
    UserName = result.UserName,
    ExternalLoginData = loginData
});

다음과 같이 변경합니다:

return View("ExternalLoginConfirmation", new RegisterExternalLoginModel
{
    UserName = result.UserName,
    ExternalLoginData = loginData,
    FullName = result.ExtraData["name"],
    Link = result.ExtraData["link"]
});

이 작업은 전체 이름과 링크 속성을 추가하는 단순한 작업일 뿐입니다.

ExternalLoginConfirmation 메서드에서는 추가 사용자 정보를 저장하기 위한 코드를 추가합니다.

if (user == null)
{
    // 프로필 테이블에 이름 삽입
    UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
    db.SaveChanges();
 
    db.ExternalUsers.Add(new ExternalUserInformation
    {
        UserId = newUser.UserId,
        FullName = model.FullName,
        Link = model.Link
    });
    db.SaveChanges();
 
    OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
    OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
 
    return RedirectToLocal(returnUrl);
}
else
{
    ModelState.AddModelError("UserName", "User name already exists. Please enter a different user name.");
}

뷰 조정하기

이제 공급자로부터 받아온 사용자 추가 정보를 등록 페이지에 출력해보겠습니다.

Views/Account 폴더에 위치한 ExternalLoginConfirmation.cshtml 파일을 엽니다. 기존 사용자 이름 필드 아래에 FullName, Link, 그리고 PictureLink에 대한 필드를 추가합니다.

<li>
    @Html.LabelFor(m => m.FullName)
    @Html.TextBoxFor(m => m.FullName)
</li>
<li>
    @Html.LabelFor(m => m.Link)
    @Html.TextBoxFor(m => m.Link)
</li>

이제 응용 프로그램을 실행해서 추가 정보와 함께 새로운 사용자를 저장할 준비가 대부분 마무리되었습니다. 테스트를 해보려면 사이트에 등록되지 않은 새로운 계정이 필요합니다. 다른 테스트 계정을 이용하거나 UserProfile 테이블과 webpages_OAuthMembership 테이블에서 재사용하고자 하는 계정의 로우를 삭제해도 됩니다. 그러면 해당 계정을 이용해서 등록 과정을 다시 수행할 수 있습니다.

응용 프로그램을 실행하고 새로운 사용자를 등록해봅니다. 그러면, 이번에는 확인 페이지에 더 많은 정보들이 나타나는 것을 확인할 수 있습니다.

register

다시 사용자 등록을 마치고 브라우저를 닫습니다. 그리고, ExtraUserInformation 테이블에 저장된 새로운 값들을 살펴보시기 바랍니다.

NuGet 패키지를 이용해서 페이스북 API 설치하기

페이스북은 다양한 작업을 수행하기 위해서 호출할 수 있는 API를 제공해줍니다. 개발자들은 HTTP 요청을 직접 전송하거나, 그런 요청의 전송을 용이하게 해주는 NuGet 패키지를 설치한 다음 이를 이용할 수도 있습니다. 본 자습서에서는 NuGet 패키지를 설치하고 사용하는 방법을 살펴보고 있지만, 그렇다고 해서 반드시 NuGet 패키지를 설치해야만 하는 것은 아닙니다. 본 자습서에서는 페이스북 C# SDK 패키지를 사용하는 방법을 살펴볼 것입니다. 물론, 페이스북 API 호출을 지원해주는 다른 NuGet 패키지들도 존재합니다.

솔루션용 NuGet 패키지 관리(Manage NuGet Packages) 대화 상자에서 페이스북 C# SDK 패키지를 선택합니다.

install package

본 자습서에서는 사용자의 엑세스 토큰 요청 작업을 호출하기 위해서 페이스북 C# SDK를 사용해볼 것입니다. 다음 절에서는 엑세스 토큰을 가져오는 방법을 살펴봅니다.

엑세스 토큰 가져오기

대부분의 외부 공급자들은 사용자의 신원계정이 검증된 직후에 엑세스 토큰을 다시 반환해줍니다. 이 엑세스 토큰은 오직 인증된 사용자만 호출할 수 있는 작업들을 수행할 수 있게 해주기 때문에 대단히 중요합니다. 따라서, 보다 다양한 기능을 제공해주고자 할 때에는 엑세스 토큰을 조회하여 저장하는 작업이 필수적입니다.

특정 외부 공급자는 한정된 횟수까지만 엑세스 토큰을 유효한 것으로 간주하는 경우도 있습니다. 따라서, 항상 유효한 엑세스 토큰을 보유하려면 이를 데이터베이스에 저장하기 보다는 매번 사용자가 로그인 할 때마다 조회해서 세션 값으로 보유하는 편이 바람직합니다.

엑세스 토큰도 ExternalLoginCallback 메서드에서 AuthenticationResult 개체의 ExtraData 속성을 통해서 반환됩니다. ExternalLoginCallback 메서드에 다음에 강조된 코드를 추가해서 Session 개체에 엑세스 토큰을 저장합니다. 이 코드는 사용자가 페이스북 계정으로 로그인 할 때마다 매번 수행되게 됩니다.

[AllowAnonymous]
public ActionResult ExternalLoginCallback(string returnUrl)
{
    AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(
        Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
    if (!result.IsSuccessful)
    {
        return RedirectToAction("ExternalLoginFailure");
    }
 
    if (result.ExtraData.Keys.Contains("accesstoken"))
    {
        Session["facebooktoken"] = result.ExtraData["accesstoken"];
    }
 
    if (OAuthWebSecurity.Login(
        result.Provider,
        result.ProviderUserId,
        createPersistentCookie: false))
    {
        return RedirectToLocal(returnUrl);
    }
 
    if (User.Identity.IsAuthenticated)
    {
        // 현재 사용자가 로그인한 경우 새 계정을 추가하십시오.
        OAuthWebSecurity.CreateOrUpdateAccount(
            result.Provider,
            result.ProviderUserId,
            User.Identity.Name);
        return RedirectToLocal(returnUrl);
    }
    else
    {
        // 사용자가 새 사용자입니다. 원하는 멤버 자격 이름을 물어봅니다.
        string loginData = OAuthWebSecurity.SerializeProviderUserId(
            result.Provider,
            result.ProviderUserId);
        ViewBag.ProviderDisplayName =
            OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName;
        ViewBag.ReturnUrl = returnUrl;
        return View("ExternalLoginConfirmation", new RegisterExternalLoginModel
        {
            UserName = result.UserName,
            ExternalLoginData = loginData,
            FullName = result.ExtraData["name"],
            Link = result.ExtraData["link"]
        });
    }
}

비록, 이번 예제에서는 페이스북에서 엑세스 토큰을 가져오고 있지만, 다른 모든 외부 공급자들에서도 동일한 "accesstoken"이라는 키 이름을 사용하여 엑세스 토큰을 가져올 수 있습니다.

사용자가 로그아웃 한 뒤에도 토큰이 남아 있는 것을 방지하기 위해서 다음에 강조된 코드를 AccountController 클래스의 LogOff 메서드에 추가합니다.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
    WebSecurity.Logout();
    Session.Remove("facebooktoken");
 
    return RedirectToAction("Index", "Home");
}

엑세스 토큰을 이용해서 사용자 정보 가져오기

이제 엑세스 토큰도 준비됐고 페이스북 C# SDK 패키지도 설치했으므로, 이 두 가지를 함께 사용해서 페이스북에 추가 사용자 정보를 요청할 수 있습니다. ExternalLoginConfirmation 메서드에서 엑세스 토큰 값을 매개변수로 전달하여 FacebookClient 클래스의 인스턴스를 생성합니다. 그리고, 현재 인증된 사용자에 대한 verified 속성의 값을 요청합니다. 이 verified 속성은 휴대전화로 메시지를 발송하는 등과 같은 다른 방법으로 계정의 유효성을 검증했는지 여부를 나타냅니다. 그리고, 그 값을 데이터베이스에 저장합니다.

if (user == null)
{
    // 프로필 테이블에 이름 삽입
    UserProfile newUser = db.UserProfiles.Add(new UserProfile { UserName = model.UserName });
    db.SaveChanges();
 
    bool facebookVerified;
 
    var client = new Facebook.FacebookClient(Session["facebooktoken"].ToString());
    dynamic response = client.Get("me", new { fields = "verified" });
    if (response.ContainsKey("verified"))
    {
        facebookVerified = response["verified"];
    }
    else
    {
        facebookVerified = false;
    }
 
    db.ExternalUsers.Add(new ExternalUserInformation
    {
        UserId = newUser.UserId,
        FullName = model.FullName,
        Link = model.Link,
        Verified = facebookVerified
    });
    db.SaveChanges();
 
    OAuthWebSecurity.CreateOrUpdateAccount(provider, providerUserId, model.UserName);
    OAuthWebSecurity.Login(provider, providerUserId, createPersistentCookie: false);
 
    return RedirectToLocal(returnUrl);
}

이번에도 테스트를 수행하려면 데이터베이스에서 사용자 레코드를 삭제하거나 다른 페이스북 계정을 사용해야 합니다.

다시 응용 프로그램을 실행하고 새로운 사용자를 등록해봅니다. 그리고, ExtraUserInformation 케이블에서 Verified 속성의 값을 확인해봅니다.

정리

본 자습서에서는 페이스북과 사용자 인증 및 데이터 등록이 통합된 웹 사이트를 구축해봤습니다. 그리고, MVC 4 웹 응용 프로그램에 설정되어 있는 기본 동작과 그 기본 동작을 사용자 정의하는 방법을 배웠봤습니다.