Статьи

Windows Phone: включение аутентификации на сайтах социальных сетей

Включение аутентификации с использованием сайтов социальных сетей (Facebook, Twitter, Live и Google) в приложении Windows Phone может быть немного трудным. Реализация одного достаточно проста, если вы понимаете рабочий процесс взад и вперед. После добавления нескольких источников аутентификации может возникнуть много проблем и повторного кода. Инфраструктура придумала хорошее решение для этого. В их продукте NetAdvantage для Windows Phone есть элемент управления ACS.

Поскольку все 4 сайта используют oAuth для аутентификации (oAuth 1.0a для Twitter и oAuth 2.0 для Live ID, Gmail и Facebook), объединенный контроль имеет большой смысл. После входа в систему пользовательские данные становятся доступными для создания профиля пользователя или любого другого, для которого он вам нужен. Возвращенный токен аутентификации также доступен для последующих звонков на сайты аутентификации. Поскольку этот элемент управления охватывает только проверку подлинности, вам потребуется реализовать собственное решение, если вам нужно взаимодействовать с веб-службой.

Первое, что вам нужно сделать, это зайти на страницу Infragistics NetAdvantage для Windows Phone и загрузить пробную версию. Пока он устанавливается, вам следует перейти на Facebook и создать приложение, если вы еще этого не сделали.

Facebook https://developers.facebook.com/apps

Другие поддерживаемые поставщики:

Twitter https://dev.twitter.com/apps/new
Live ID https://manage.dev.live.com/AddApplication.aspx
Google https : //code.google.com/apis/console/? pli = 1

Когда у вас есть значения ИД приложения / Ключа API и Секрета приложения, вы можете открыть Visual Studio 2010 и либо запустить новое решение и следовать за ним, либо загрузить завершенное решение и откройте его. Я предлагаю вам загрузить законченное решение, поскольку оно содержит части, которые я не описал, которые важны для его функционирования.

После создания добавьте ссылку на InfragisticsWP7.Controls.Authentication.v12.1.dll. На моем 64-разрядном компьютере он установлен в «C: \ Program Files (x86) \ Infragistics \ NetAdvantage 2012.1 \ Windows Phone \ Bin \».

Теперь откройте файл MainPage.xaml и добавьте следующее в тег «phone: PhoneApplicationPage» в верхней части файла: 

xmlns:ig="clr-namespace:Infragistics.Controls.Authentication;assembly=InfragisticsWP7.Controls.Authentication.v12.1"

Теперь мы добавляем в Grid ContentPanel следующее:

<ig:XamAccessControlCatalog x:Name="FacebookLogin" >
	<ig:XamAccessControlCatalog.AuthenticationServices>
		<ig:AuthenticationService 
			Provider="Facebook"
			ClientId="xxxxxxxxxxxxxxxx"
			RedirectUri="http://www.facebook.com/connect/login_success.html">
			<ig:AuthenticationService.Scopes>
				<System:String>email</System:String>
			</ig:AuthenticationService.Scopes>
		</ig:AuthenticationService>
	</ig:XamAccessControlCatalog.AuthenticationServices>
</ig:XamAccessControlCatalog>

 Этот xaml включает список всех провайдеров аутентификации, которые вы настроили. В этом примере используется только Facebook, но вы можете добавить других.

Я пропускаю несколько мелких деталей настройки ACS Control. Вы можете найти документацию и еще несколько примеров кода здесь:

< http://help.infragistics.com/Help/NetAdvantage/WindowsPhone/2012.1/CLR4.0/html/xamAccessControl_Using_xamAccessControl.html >

Теперь в файле MainPage.xaml.cs мы изменим конструктор, добавив 3 обработчика событий и их код:

public MainPage()
{
	InitializeComponent();

	FacebookLogin.AuthenticationCompleted += LoginAuthenticationCompleted;
	FacebookLogin.AuthenticationDenied += LoginAuthenticationDenied;
	FacebookLogin.AuthenticationException += LoginAuthenticationException;

}
void LoginAuthenticationException(object sender, Infragistics.Controls.Authentication.AuthenticationExceptionEventArgs e)
{
	MessageBox.Show("Authentication Exception:" + e.Exception.Message);
}

void LoginAuthenticationDenied(object sender, Infragistics.Controls.Authentication.AuthenticationDeniedEventArgs e)
{
	MessageBox.Show("Authentication Denied:" + e.AuthenticationDeniedResult.Error);
}

void LoginAuthenticationCompleted(object sender, Infragistics.Controls.Authentication.AuthenticationCompletedEventArgs e)
{
	MessageBox.Show("Authentication Completed:" + e.AuthenticationResult.AuthenticationToken);
	FillViewModel(e.AuthenticationResult.UserData);
	NavigationService.Navigate(new Uri("/Views/UserDetails.xaml", UriKind.Relative));
}

 Чтобы отобразить возвращенные пользовательские данные, я использовал что-то не совсем MVVM, потому что нет модели, но для простоты модель была опущена.

Чтобы сделать ViewModel доступным для всех страниц, мы определяем свойство ViewModel в App.xaml.cs:

private static PersonViewModel viewModel = null;
public static PersonViewModel ViewModel
{
	get
	{
		// Delay creation of the view model until necessary
		if (viewModel == null)  
			viewModel = new PersonViewModel();

		return viewModel;
	}
}

Приведенный выше код проверяет свойство viewModel, чтобы увидеть, было ли оно установлено, если нет, то создает экземпляр типа ViewModel. Теперь, когда мы успешно аутентифицируемся и происходит событие AuthenticationCompleted, мы вызываем функцию FillViewModel, которая заполняет ViewModel «

private void FillViewModel(Dictionary<string, string> userData)
{
	App.ViewModel.Username = userData.Single(r => r.Key == "username").Value;
	App.ViewModel.Name = userData.Single(r => r.Key == "name").Value;
	App.ViewModel.Gender = userData.Single(r => r.Key == "gender").Value;
	App.ViewModel.Email = userData.Single(r => r.Key == "email").Value;
	App.ViewModel.Link = userData.Single(r => r.Key == "link").Value;
	App.ViewModel.Bio = userData.Single(r => r.Key == "bio").Value;
	App.ViewModel.Quotes = userData.Single(r => r.Key == "quotes").Value;
}

 Теперь, когда свойство App.ViewModel заполнено данными пользователя, теперь мы можем добавить представление с именем UserData.xaml и открыть файл UserDetails.xaml.cs. В конструкторе установите DataContext для свойства App.ViewModel.

public UserDetails()
{
	InitializeComponent();
	DataContext = App.ViewModel;
}

Теперь мы добавляем наши TextBlocks в ScrollViewer и StackPanel. Это позволяет красиво складывать данные и прокручивать их, если у вас есть данные на нескольких экранах:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
	<ScrollViewer>
		<StackPanel>
			<TextBlock Name="UserNameLabel" Text="Username" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<TextBlock Name="UserNameTextBlock" Text="{Binding Username}" Margin="10" FontSize="{StaticResource PhoneFontSizeNormal}" />
			
			<TextBlock Name="GenderLabel" Text="Gender" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<TextBlock Name="GenderTextBlock" Text="{Binding Gender}" Margin="10" FontSize="{StaticResource PhoneFontSizeNormal}" />

			<TextBlock Name="EmailLabel" Text="Email" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<StackPanel Orientation="Horizontal">
				<TextBlock Name="EmailTextBlock" Text="{Binding Email}" Margin="10" FontSize="{StaticResource PhoneFontSizeNormal}" Tap="EmailImage_Tap"  />
					<Image Height="48" Name="EmailImage" Stretch="Fill" Width="48" Source="/Images/Mail.png" Tap="EmailImage_Tap" />
			</StackPanel>
			
			<TextBlock Name="LinkLabel" Text="Link" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<StackPanel Orientation="Horizontal">
				<TextBlock Name="LinkTextBlock" Margin="10" Text="{Binding Link}" FontSize="{StaticResource PhoneFontSizeNormal}" Tap="LinkImage_Tap"/>
				<Image Height="48" Name="LinkImage" Stretch="Fill" Width="48" Source="/Images/Internet Explorer.png" Tap="LinkImage_Tap" />
			</StackPanel>

			<TextBlock Name="BioLabel" Text="Bio" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<TextBlock Name="BioTextBlock" Text="{Binding Bio}" TextWrapping="Wrap" Margin="10" FontSize="{StaticResource PhoneFontSizeNormal}" />

			<TextBlock Name="QuotesLabel" Text="Quotes" Foreground="{StaticResource PhoneAccentBrush}" FontSize="{StaticResource PhoneFontSizeMedium}"/>
			<TextBlock Name="QuotesTextBlock" Text="{Binding Quotes}" TextWrapping="Wrap" Margin="10" FontSize="{StaticResource PhoneFontSizeNormal}" />
		</StackPanel>
	</ScrollViewer>
</Grid>

 В этом примере я сделал адреса электронной почты и адреса страниц Facebook доступными. Нажатие на адрес электронной почты открывает ComposeEmailTask, а адрес веб-страницы открывает WebBrowserTask. Я проверил, чтобы убедиться, что URL или адрес электронной почты действительно заполнены. Я также обертываю каждый в структуру try-catch и ловлю определенное событие. Если вы быстро нажмете кнопку или подобные ей триггеры и задачи, будет выдано исключение InvalidOperationException. Я специально ловлю это исключение и игнорирую его. Затем я допускаю любые другие исключения. Честно говоря, я не знаю, является ли это хорошей практикой, но я использую ее во всех своих приложениях, чтобы предотвратить эту конкретную ошибку.

private void LinkImage_Tap(object sender, GestureEventArgs e)
{
	try
	{
		if (!String.IsNullOrEmpty(LinkTextBlock.Text))
		{
			var browserTask = new WebBrowserTask();
			browserTask.Uri = new Uri(LinkTextBlock.Text, UriKind.Absolute);
			browserTask.Show();
		}
	}
	catch(InvalidOperationException ex)
	{
		if (ex.Message != "Navigation is not allowed when the task is not in the foreground. Error: -2147220990")
			throw ex;
	}
}

private void EmailImage_Tap(object sender, GestureEventArgs e)
{
	try
	{
		if (!String.IsNullOrEmpty(EmailTextBlock.Text))
		{
			var mailTask = new EmailComposeTask();
			mailTask.To = EmailTextBlock.Text;
			mailTask.Show();
		}
	}
	catch (InvalidOperationException ex)
	{
		if (ex.Message != "Navigation is not allowed when the task is not in the foreground. Error: -2147220990")
			throw ex;
	}
}

Теперь, когда мы пошли по этому примеру, вы можете видеть, что для отображения информации о пользователе требуется значительно больше работы, чем для ее получения. Все, что нужно, это добавить элемент управления в ваш файл xaml и прослушать 3 события. Добавить возможность собирать информацию, заполнять формы регистрации и страницы профиля чрезвычайно просто с помощью элемента управления Infragistics.

Несмотря на то, что это платный контроль, он экономит время, позволяя пользователям войти в систему и получать от них очень ценные пользовательские данные, более чем компенсируя цену в 99 долларов. В настоящее время я использую пробную версию и буду использовать ее в будущих приложениях, которые я напишу. Использование ShareStatusTask и ShareLinkTasks работает в некоторых случаях, и я использовал их, но если вы хотите, чтобы имя вашего приложения связывалось с тем, чтобы помочь вам опубликовать, вы должны пройти аутентификацию и получить разрешение пользователей. По моему мнению, если я смогу сэкономить пару часов, внедряя аутентификацию в одном приложении, оно окупится.