Seletor de Arquivos
O Seletor de Arquivos v8 permite que você use a mesma funcionalidade usada no serviço M365 em suas soluções. Ou seja, à medida que iteramos e aprimoramos o serviço, esses novos recursos aparecem para seus usuários!
Esse novo "controle" é uma página hospedada no serviço Microsoft com a qual você interage por meio de mensagens de postagem. A página pode ser hospedada inserida em um iframe ou como pop-up.
Mostrar-me o código de exemplo
Você pode encontrar a documentação do seletor 7.2 aqui.
Configuração necessária
Para executar os exemplos ou usar o controle em sua solução, você precisará criar um aplicativo do AAD. Você pode seguir estas etapas:
- Crie um novo Registro de Aplicativo do AAD e anote a ID do aplicativo
- Em autenticação, crie um registro de aplicativo de página única
- Defina o URI de redirecionamento como
https://localhost
(isso é para testar os exemplos) - Verifique se os tokens de acesso e os tokens de ID estão marcados
- Opcionalmente, você pode configurar este aplicativo para multilocatário, mas isso está fora do escopo deste artigo
- Defina o URI de redirecionamento como
- Em permissões de API
- Adicionar
Files.Read.All
,Sites.Read.All
, deixarUser.Read
para permissões delegadas do Graph - Adicionar
AllSites.Read
,MyFiles.Read
para permissões delegadas do SharePoint
- Adicionar
Se você estiver desenvolvendo na Estrutura do SharePoint poderá solicitar essas permissões no manifesto do aplicativo com os recursos "SharePoint" e "Microsoft Graph".
Para permitir que o usuário carregue arquivos e crie pastas na experiência do Picker, você pode solicitar acesso a
Files.ReadWrite.All
,Sites.ReadWrite.All
,AllSites.Write
, eMyFiles.Write
.
Permissões
O seletor de ficheiros funciona sempre com permissões delegadas e, como tal, só pode aceder a ficheiros e pastas às quais o utilizador atual já tem acesso.
No mínimo, tem de pedir ao SharePoint MyFiles.permissão de Ler para ler ficheiros a partir dos sites do OneDrive e do SharePoint de um utilizador.
Reveja a tabela abaixo para compreender que permissão é necessária com base nas operações que pretende efetuar. Todas as permissões nesta tabela referem-se a permissões delegadas.
Ler | Gravar | |
---|---|---|
OneDrive | SharePoint.MyFiles.Read ou Graph.Files.Read |
SharePoint.MyFiles.Write ou Graph.Files.ReadWrite |
SharePoint Sites | SharePoint.MyFiles.Read ou Graph.Files.Read ou SharePoint.AllSites.Read |
SharePoint.MyFiles.Write ou Graph.Files.ReadWrite ou SharePoint.AllSites.Write |
Canais do Teams | Graph.ChannelSettings.Read.All e SharePoint.AllSites.Read | Graph.ChannelSettings.Read.All e SharePoint.AllSites.Write |
Como funciona
Para usar o controle, você deve:
- Faça uma solicitação POST para a página "controle" hospedada em /_layouts/15/FilePicker.aspx. Ao usar essa solicitação, você fornece alguns parâmetros, o principal é a configuração do seletor.
- Configure o sistema de mensagens entre o aplicativo host e o controle usando postMessage e portas de mensagem.
- Depois que o canal de comunicação for estabelecido, você deverá responder a vários "comandos", o primeiro deles é fornecer tokens de autenticação.
- Por fim, você precisará responder a mensagens de comando adicionais para fornecer tokens de autenticação novos/diferentes, manipular arquivos selecionados ou fechar o pop-up.
As seções a seguir explicam melhor cada cenário.
Também temos uma variedade de exemplos que mostram diferentes maneiras de se integrar ao controle.
Iniciar o Seletor
Para iniciar o seletor, você precisa criar uma "janela", que pode ser um iframe ou um pop-up. Depois de ter uma janela, você deve construir um formulário e fazer POST do formulário para a URL {baseUrl}/_layouts/15/FilePicker.aspx
com os parâmetros de cadeia de caracteres de consulta definidos.
O valor {baseUrl}
acima é a URL da Web do SharePoint da Web de destino ou o OneDrive do usuário. Alguns exemplos são: "https://tenant.sharepoint.com/sites/dev" ou "https://tenant-my.sharepoint.com".
Configuração do Consumidor do OneDrive
nome | descrições |
---|---|
autoridade | https://login.microsoftonline.com/consumers |
Escopo | OneDrive.ReadWrite ou OneDrive.ReadOnly |
baseUrl | https://onedrive.live.com/picker |
Quando pedir um token, irá utilizar o
OneDrive.ReadOnly
ouOneDrive.ReadWrite
quando pedir o token. Quando pedir as permissões para a sua aplicação, irá selecionar paraFiles.Read
ouFiles.ReadWrite
(ou outro âmbito Ficheiros.X).
// create a new window. The Picker's recommended maximum size is 1080x680, but it can scale down to
// a minimum size of 250x230 for very small screens or very large zoom.
const win = window.open("", "Picker", "width=1080,height=680");
// we need to get an authentication token to use in the form below (more information in auth section)
const authToken = await getToken({
resource: baseUrl,
command: "authenticate",
type: "SharePoint",
});
// to use an iframe you can use code like:
// const frame = document.getElementById("iframe-id");
// const win = frame.contentWindow;
// now we need to construct our query string
// options: These are the picker configuration, see the schema link for a full explaination of the available options
const queryString = new URLSearchParams({
filePicker: JSON.stringify(options),
locale: 'en-us'
});
// Use MSAL to get a token for your app, specifying the resource as {baseUrl}.
const accessToken = await getToken(baseUrl);
// we create the absolute url by combining the base url, appending the _layouts path, and including the query string
const url = baseUrl + `/_layouts/15/FilePicker.aspx?${queryString}`);
// create a form
const form = win.document.createElement("form");
// set the action of the form to the url defined above
// This will include the query string options for the picker.
form.setAttribute("action", url);
// must be a post request
form.setAttribute("method", "POST");
// Create a hidden input element to send the OAuth token to the Picker.
// This optional when using a popup window but required when using an iframe.
const tokenInput = win.document.createElement("input");
tokenInput.setAttribute("type", "hidden");
tokenInput.setAttribute("name", "access_token");
tokenInput.setAttribute("value", accessToken);
form.appendChild(tokenInput);
// append the form to the body
win.document.body.append(form);
// submit the form, this will load the picker page
form.submit();
Configuração do Seletor
O seletor é configurado por meio da serialização de um objeto json que contém as configurações desejadas e do acréscimo dele aos valores de querystring, conforme mostrado na seção Iniciar o Seletor. Você também pode exibir o esquema completo. No mínimo, você deve fornecer as configurações de autenticação, entrada e mensagens.
Um exemplo de objeto de configurações mínimas é mostrado abaixo. Isso configura o sistema de mensagens no canal 27, permite que o seletor saiba que podemos fornecer tokens e que queremos que a guia "Meus Arquivos" represente os arquivos do OneDrive do usuário. Essa configuração usaria uma baseUrl do formato "https://{tenant}-my.sharepoint.com";
const channelId = uuid(); // Always use a unique id for the channel when hosting the picker.
const options = {
sdk: "8.0",
entry: {
oneDrive: {}
},
// Applications must pass this empty `authentication` option in order to obtain details item data
// from the picker, or when embedding the picker in an iframe.
authentication: {},
messaging: {
origin: "http://localhost:3000",
channelId: channelId
},
}
O seletor foi projetado para funcionar em ambos OneDrive OU SharePoint em uma determinada instância e apenas uma das seções de entrada deve ser incluída.
Localização
A interface do Seletor de Arquivos oferece suporte à localização para o mesmo conjunto de idiomas do SharePoint.
Para definir o idioma do seletor de arquivos, use o parâmetro locale
de string de consulta, definido como um dos valores LCID na lista acima.
Estabelecer Mensagens
Depois que a janela for criada e o formulário enviado, você precisará estabelecer um canal de mensagens. Isso é usado para receber os comandos do seletor e responder.
let port: MessagePort;
function initializeMessageListener(event: MessageEvent): void {
// we validate the message is for us, win here is the same variable as above
if (event.source && event.source === win) {
const message = event.data;
// the channelId is part of the configuration options, but we could have multiple pickers so that is supported via channels
// On initial load and if it ever refreshes in its window, the Picker will send an 'initialize' message.
// Communication with the picker should subsequently take place using a `MessageChannel`.
if (message.type === "initialize" && message.channelId === options.messaging.channelId) {
// grab the port from the event
port = event.ports[0];
// add an event listener to the port (example implementation is in the next section)
port.addEventListener("message", channelMessageListener);
// start ("open") the port
port.start();
// tell the picker to activate
port.postMessage({
type: "activate",
});
}
}
};
// this adds a listener to the current (host) window, which the popup or embed will message when ready
window.addEventListener("message", messageEvent);
Implementação do Ouvinte de Mensagens
Sua solução deve lidar com várias mensagens do seletor, classificadas como notificações ou comandos. As notificações não esperam resposta e podem ser consideradas informações de log. A única exceção é a notificação page-loaded
realçada abaixo, que informará que o seletor está pronto.
Os comandos exigem que você reconheça e, dependendo do comando, responda. Esta seção mostra um exemplo de implementação da função channelMessageListener
adicionada como um ouvinte de eventos à porta. As próximas seções falam detalhadamente sobre notificações e comandos.
async function channelMessageListener(message: MessageEvent): Promise<void> {
const payload = message.data;
switch (payload.type) {
case "notification":
const notification = payload.data;
if (notification.notification === "page-loaded") {
// here we know that the picker page is loaded and ready for user interaction
}
console.log(message.data);
break;
case "command":
// all commands must be acknowledged
port.postMessage({
type: "acknowledge",
id: message.data.id,
});
// this is the actual command specific data from the message
const command = payload.data;
// command.command is the string name of the command
switch (command.command) {
case "authenticate":
// the first command to handle is authenticate. This command will be issued any time the picker requires a token
// 'getToken' represents a method that can take a command and return a valid auth token for the requested resource
try {
const token = await getToken(command);
if (!token) {
throw new Error("Unable to obtain a token.");
}
// we report a result for the authentication via the previously established port
port.postMessage({
type: "result",
id: message.data.id,
data: {
result: "token",
token: token,
}
});
} catch (error) {
port.postMessage({
type: "result",
id: message.data.id,
data: {
result: "error",
error: {
code: "unableToObtainToken",
message: error.message
}
}
});
}
break;
case "close":
// in the base of popup this is triggered by a user request to close the window
await close(command);
break;
case "pick":
try {
await pick(command);
// let the picker know that the pick command was handled (required)
port.postMessage({
type: "result",
id: message.data.id,
data: {
result: "success"
}
});
} catch (error) {
port.postMessage({
type: "result",
id: message.data.id,
data: {
result: "error",
error: {
code: "unusableItem",
message: error.message
}
}
});
}
break;
default:
// Always send a reply, if if that reply is that the command is not supported.
port.postMessage({
type: "result",
id: message.data.id,
data: {
result: "error",
error: {
code: "unsupportedCommand",
message: command.command
}
}
});
break;
}
break;
}
}
Obter Token
O controlo requer que possamos fornecer tokens de autenticação com base no comando enviado. Para tal, criamos um método que utiliza um comando e devolve um token, conforme mostrado abaixo. Estamos a utilizar o @azure/msal-browser
pacote para processar o trabalho de autenticação.
Atualmente, o controlo depende de tokens do SharePoint e não do Graph, pelo que terá de garantir que o recurso está correto e que não pode reutilizar tokens para chamadas do Graph.
import { PublicClientApplication, Configuration, SilentRequest } from "@azure/msal-browser";
import { combine } from "@pnp/core";
import { IAuthenticateCommand } from "./types";
const app = new PublicClientApplication(msalParams);
async function getToken(command: IAuthenticateCommand): Promise<string> {
let accessToken = "";
const authParams = { scopes: [`${combine(command.resource, ".default")}`] };
try {
// see if we have already the idtoken saved
const resp = await app.acquireTokenSilent(authParams!);
accessToken = resp.accessToken;
} catch (e) {
// per examples we fall back to popup
const resp = await app.loginPopup(authParams!);
app.setActiveAccount(resp.account);
if (resp.idToken) {
const resp2 = await app.acquireTokenSilent(authParams!);
accessToken = resp2.accessToken;
} else {
// throw the error that brought us here
throw e;
}
}
return accessToken;
}
Resultados do Item Escolhidos
Quando um item é selecionado, o seletor irá devolver, através do canal de mensagens, uma matriz de itens selecionados. Embora exista um conjunto de informações que podem ser devolvidas, é sempre garantido que o seguinte seja incluído:
{
"id": string,
"parentReference": {
"driveId": string
},
"@sharePoint.endpoint": string
}
Com isto, pode criar um URL para fazer um pedido GET para obter as informações necessárias sobre o ficheiro selecionado. Geralmente, seria da forma:
@sharePoint.endpoint + /drives/ + parentReference.driveId + /items/ + id
Terá de incluir um token válido com os direitos adequados para ler o ficheiro no pedido.
Carregar Ficheiros
Se conceder Files.ReadWrite.All
permissões à aplicação que está a utilizar para tokens de seletor, será apresentado um widget no menu superior, permitindo-lhe carregar ficheiros e pastas para a biblioteca de documentos do OneDrive ou do SharePoint. Não são necessárias outras alterações de configuração. Este comportamento é controlado pelas permissões de aplicação + utilizador. Tenha em atenção que, se o utilizador não tiver acesso à localização a carregar, o seletor não mostrará a opção.
Documentação de Orientação sobre a Imagem Corporativa
As aplicações que se integram com o Selecionador de Ficheiros do Microsoft OneDrive também podem optar por promover a sua integração com o OneDrive para os clientes. Uma vez que o OneDrive tem uma oferta de consumidor e comercial, as seguintes opções estão disponíveis para apresentação em interfaces de aplicações de terceiros:
- Microsoft OneDrive (pessoal)
- Também pode ser apresentado como Microsoft OneDrive para pessoal
- Microsoft OneDrive (trabalho/escola)
- Também pode ser apresentado como Microsoft OneDrive para trabalho ou escola