📄 x6351.htm
字号:
<HTML
><HEAD
><TITLE
>User Registration</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.64
"><LINK
REL="HOME"
TITLE="Programming Jabber"
HREF="book1.htm"><LINK
REL="UP"
TITLE="User Registration and Authorization"
HREF="c6313.htm"><LINK
REL="PREVIOUS"
TITLE="XML Stream Flow"
HREF="x6334.htm"><LINK
REL="NEXT"
TITLE="User Authentication"
HREF="x6569.htm"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Programming Jabber</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x6334.htm"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 6. User Registration and Authorization</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x6569.htm"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="JABTDG-CH-6-SECT-5.2"
>User Registration</A
></H1
><P
>User registration with a Jabber <I
CLASS="EMPHASIS"
>server</I
> specifically
means the creation (or modification) of a user account for the JSM
component - the component that provides the basic IM services and has
a notion of users and user sessions. It takes place at the start of a
connection to a Jabber server, as does user authentication, as shown
in <A
HREF="x6334.htm#JABTDG-CH-6-FIG-1"
>Figure 6-1</A
>.</P
><P
>Let's take a look at the XML fragments involved in
a typical user registration process. <A
HREF="x6351.htm#JABTDG-CH-6-EX-1"
>Example 6-1</A
>
shows the XML stream header exchange and the IQ packets in the
<TT
CLASS="LITERAL"
>jabber:iq:register</TT
> namespace.</P
><DIV
CLASS="EXAMPLE"
><A
NAME="JABTDG-CH-6-EX-1"
></A
><P
><B
>Example 6-1. A typical user registration process</B
></P
><P
>First, the XML stream header exchange</P
><P
> <PRE
CLASS="SCREEN"
>SEND: <?xml version='1.0'?>
<stream:stream to='yak' xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
RECV: <?xml version='1.0'?>
<stream:stream xmlns:stream='http://etherx.jabber.org/streams'
id='3B2DB1A7' xmlns='jabber:client' from='yak'></PRE
></P
><P
>Then the client sends a request to discover what information must be
passed to the Jabber server to register a new user:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get'>
<query xmlns='jabber:iq:register'/>
</iq>
RECV: <iq type='result'>
<query xmlns='jabber:iq:register'>
<instructions>
Choose a username and password to register with this server.
</instructions>
<name/>
<email/>
<username/>
<password/>
</query>
</iq></PRE
></P
><P
>The client does as asked, and sends the required information, which results
in a successful new user registration:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set'>
<query xmlns='jabber:iq:register'>
<username>leslie</username>
<password>secret</password>
<email>lel@plevna.com</email>
<name>Leslie Hawke</name>
</query>
</iq>
RECV: <iq type='result'/></PRE
></P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-6-SECT-5.2.1"
>Configuration and Module Load Directives</A
></H2
><P
>Lets start by reviewing the relevant configuration in
<TT
CLASS="FILENAME"
>jabber.xml</TT
>. User registration is a JSM feature, and
we find two places of interest in that component instance definition.
The first is in that instance's configuration, in the section qualified
by the <TT
CLASS="LITERAL"
>jabber:config:jsm</TT
> namespace:</P
><P
><PRE
CLASS="SCREEN"
><register notify="yes">
<instructions>
Choose a username and password to register with this server.
</instructions>
<name/>
<email/>
</register></PRE
></P
><P
>The second is in that instance's connection method, showing the
<TT
CLASS="LITERAL"
>mod_register</TT
> module being loaded. The module
plays a major part in handling the registration process, but there
are others too, as we will see. </P
><P
><PRE
CLASS="SCREEN"
><load main="jsm">
<jsm>./jsm/jsm.so</jsm>
<mod_echo>./jsm/jsm.so</mod_echo>
<mod_roster>./jsm/jsm.so</mod_roster>
<mod_time>./jsm/jsm.so</mod_time>
<mod_vcard>./jsm/jsm.so</mod_vcard>
<mod_last>./jsm/jsm.so</mod_last>
<mod_version>./jsm/jsm.so</mod_version>
<mod_announce>./jsm/jsm.so</mod_announce>
<mod_agents>./jsm/jsm.so</mod_agents>
<mod_browse>./jsm/jsm.so</mod_browse>
<mod_admin>./jsm/jsm.so</mod_admin>
<mod_filter>./jsm/jsm.so</mod_filter>
<mod_offline>./jsm/jsm.so</mod_offline>
<mod_presence>./jsm/jsm.so</mod_presence>
<mod_auth_plain>./jsm/jsm.so</mod_auth_plain>
<mod_auth_digest>./jsm/jsm.so</mod_auth_digest>
<mod_auth_0k>./jsm/jsm.so</mod_auth_0k>
<mod_log>./jsm/jsm.so</mod_log>
<TT
CLASS="USERINPUT"
><B
><mod_register>./jsm/jsm.so</mod_register></B
></TT
>
<mod_xml>./jsm/jsm.so</mod_xml>
</load></PRE
></P
><P
>The <TT
CLASS="LITERAL"
><register/></TT
> configuration section
looks familiar - the contents are very similar to the IQ result returned
in response to the IQ get in the <TT
CLASS="LITERAL"
>jabber:iq:register</TT
>
namespace in <A
HREF="x6351.htm#JABTDG-CH-6-EX-1"
>Example 6-1</A
>. Indeed, to respond to
an IQ get, the <TT
CLASS="LITERAL"
>mod_register</TT
> module looks for this
<TT
CLASS="LITERAL"
><register/></TT
> section and formulates the
contents into a reply, making a simple modification as it goes - it
appends tags for the the two fields </P
><P
><PRE
CLASS="SCREEN"
><username/></PRE
></P
><P
>and</P
><P
><PRE
CLASS="SCREEN"
><password/></PRE
></P
><P
>as these two are <I
CLASS="EMPHASIS"
>always</I
> required, regardless of
configuration.</P
><P
>Removing the <TT
CLASS="LITERAL"
><register/></TT
> section from the
configuration effectively blocks the registration process, and returns
an appropriate error to the user:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get'>
<query xmlns='jabber:iq:register'/>
</iq>
RECV: <iq type='error'>
<query xmlns='jabber:iq:register'/>
<error code='501'>Not Implemented</error>
</iq></PRE
></P
><P
>Removing the reference to the <TT
CLASS="LITERAL"
>mod_register</TT
> module
from the component instance's connection method:</P
><P
><PRE
CLASS="SCREEN"
><!--
<mod_register>./jsm/jsm.so</mod_register>
--></PRE
></P
><P
>has the same effect.</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="JABTDG-CH-6-SECT-5.2.2"
>Step by Step</A
></H2
><P
>Taking the stream contents in <A
HREF="x6351.htm#JABTDG-CH-6-EX-1"
>Example 6-1</A
> step
by step, what do we see?</P
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-6-SECT-5.2.2.1"
>The XML Stream Header Exchange</A
></H3
><P
>The XML declaration that is send immediately preceding the opening
<TT
CLASS="LITERAL"
><stream:stream/></TT
> root tag is optional.
The Jabber server does not enforce its presence, and so you can
leave it out if you wish.
<A
NAME="AEN6412"
HREF="#FTN.AEN6412"
>[1]</A
>
The Jabber server will always send one in response, however.
In both cases - both streamed XML documents - the encoding is
assumed to be UTF-8.</P
><P
>For the most part, the rest of the
<TT
CLASS="LITERAL"
><stream:stream/></TT
>
root tag is static. The namespace qualifying the stream content is
<TT
CLASS="LITERAL"
>jabber:client</TT
> (which is the only namespace acceptable
when making such an XML stream connection to the <TT
CLASS="LITERAL"
>c2s</TT
>
(Client to Server)
component listening on port 5222), and the namespace qualifying the
stream itself is fixed at <TT
CLASS="LITERAL"
>http://etherx.jabber.org/streams</TT
>.
<A
NAME="AEN6420"
HREF="#FTN.AEN6420"
>[2]</A
> </P
><P
>The only think that is going to be dynamic is the <TT
CLASS="LITERAL"
>to</TT
>
attribute, which is used to specify the Jabber server name. Note that
this is the <I
CLASS="EMPHASIS"
>internal name</I
> of the Jabber server. In
our example we've already resolved the physical hostname
'<TT
CLASS="LITERAL"
>yak</TT
>' and connected to port 5222; the
<TT
CLASS="LITERAL"
>to</TT
> attribute is to specify the virtual Jabber host,
which in many cases - including an out-of-the-box
<TT
CLASS="FILENAME"
>jabber.xml</TT
> configuration - is the same as the
physical host.</P
><P
>If our Jabber server has just a single virtual host, we can use an
<TT
CLASS="LITERAL"
><alias/></TT
> configuration tag in the
<TT
CLASS="LITERAL"
>c2s</TT
> component instance configuration, as described
in <A
HREF="c3612.htm"
>Chapter 5</A
>, to remove the requirement of
specifying the <TT
CLASS="LITERAL"
>to</TT
> attribute:</P
><P
><PRE
CLASS="SCREEN"
><alias to='yak'/></PRE
></P
><P
>in the configuration section for the <TT
CLASS="LITERAL"
>c2s instance</TT
>
will set the <I
CLASS="EMPHASIS"
>default</I
> alias to 'yak' and indeed
override any value specified in the <TT
CLASS="LITERAL"
>to</TT
> attribute.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-6-SECT-5.2.2.2"
>The Query</A
></H3
><P
>While all the examples in this book follow the convention that the
opening tag name used in an IQ extension is '<TT
CLASS="LITERAL"
>query</TT
>',
we know from <A
HREF="x4089.htm#JABTDG-CH-5-SECT-5.4.3.2"
>the section called <I
>IQ Subelements</I
> in Chapter 5</A
> that in this
case, the tag name <I
CLASS="EMPHASIS"
>must</I
> be
'<TT
CLASS="LITERAL"
>query</TT
>' and nothing else. This is due to the way
that the XML is parsed by the Jabber server at this early stage in
the connection. The same is true for the user authorization case too.</P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-6-SECT-5.2.2.3"
>'Required' Fields?</A
></H3
><P
>The list of fields returned in the response to the IQ get in the
<TT
CLASS="LITERAL"
>jabber:iq:register namespace</TT
>:</P
><P
><PRE
CLASS="SCREEN"
><name/>
<email/>
<username/>
<password/></PRE
></P
><P
>is actually supposed to be a list of <I
CLASS="EMPHASIS"
>mandatory</I
>
fields. However, with the current version of the Jabber server (1.4.1,
which is our reference version for this book), this is not the case. </P
><P
>The two fields <TT
CLASS="LITERAL"
><username/></TT
> and
<TT
CLASS="LITERAL"
><password/></TT
> <I
CLASS="EMPHASIS"
>are</I
>
mandatory; not supplying, or supplying an invalid username or password
will result in an error:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='set'>
<query xmlns='jabber:iq:register'>
<username>leslie</username>
<email>lel@plevna.com</email>
<name>Leslie Hawke</name>
</query>
</iq>
RECV: <iq type='error'>
<query xmlns='jabber:iq:register'>
<username>leslie</username>
<email>lel@plevna.com</email>
<name>Leslie Hawke</name>
</query>
<error code='406'>Not Acceptable</error>
</iq></PRE
></P
><P
>However, currently, not supplying any of the other fields - the fields
that are specified in the <TT
CLASS="LITERAL"
><register/></TT
>
section of the JSM instance's configuration - will not result in an
error. This may be fixed in a later release. In any case, it's no great
loss; the details are simply stored in the user's spool file on the
server, and right now there's only one situation where this information
is subsequently
used - in answering a browse request made to a user's JID, the server
looks up the <TT
CLASS="LITERAL"
><name/></TT
> tag from the
registration data stored, and uses the value there in the browse response:</P
><P
><PRE
CLASS="SCREEN"
>SEND: <iq type='get' to='dj@yak'>
<query xmlns='jabber:iq:browse'/>
</iq>
RECV: <iq type='result' from='dj@yak' to='sabine@yak/Work'>
<user <TT
CLASS="USERINPUT"
><B
>name='DJ Adams'</B
></TT
> xmlns='jabber:iq:browse' jid='dj@yak'/>
</iq></PRE
></P
></DIV
><DIV
CLASS="SECT3"
><H3
CLASS="SECT3"
><A
NAME="JABTDG-CH-6-SECT-5.2.2.4"
>Set Without Get</A
></H3
><P
>In many of the examples of IQ throughout the book, we've seen a standard
pattern:
IQ get <TT
CLASS="LITERAL"
>-></TT
>
IQ result <TT
CLASS="LITERAL"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -